关于C#调用c++编写的DLL问题
我用C++编写了一个Player Information Database 以及相应的接口函数用于从外部操作数据库,我想要动态调用 .dll文件中的所有函数
我就拿其中几个函数做例子:
在Dll中
C/C++ code
#ifdef DB_EXPORTS
#define DB_API __declspec(dllexport)
#else
#define DB_API __declspec(dllimport)
#endif
extern "C"
{
DB_API void DB_Init(void **DB);
DB_API void DBDisplay(void *DB);
}
//用于初始化数据库
void DB_Init(void **DB)
{
CPlayerDatabase *myDB = new CPlayerDatabase();
myDB->init();
*DB = myDB;
}
//用于打印数据库
void DBDisplay(void *DB)
{
((CPlayerDatabase*)DB)->Display();
}
在C# 定义的接口类中,大家帮我看看我导入DLL的方法正确吗?
C# code
class PlayerDataBase_API
{
//因为这里是指针的指针,我觉得我的定义是错的
[DllImport("CPlayerDataBaseDll.dll"), EntryPoint = "DB_Init"]
public static extern void DB_Init(out IntPtr DB);
[DllImport("CPlayerDataBaseDll.dll"), EntryPoint = "DBDisplay"]
public static extern void DBDisplay(IntPtr DB);
}
在主函数中:
我用到了
IntPtr cpdb = Marshal.AllocHGlobal(0);
PlayerDatabase_API.DB_Init(out cpdb);
PlayerDatabase_API.DBDisplay(cpdb);
结果报错了。。。
因为我会用到很多DLL的函数,他们可以共用这个IntPtr cpdb 吗?如果是该怎么做? 还是像c++中对每个函数都要进行Load, GetProcAddress,Free.
这是我现在正在学的跨平台调用DLL,所以我还有很多问题,希望大家给我提点意见,谢谢各位。
------解决方案--------------------
建议你把 void **DB 直接定义成 int,然后内部强制转换试试看。
------解决方案--------------------因為是二級指針
所以應該是
IntPtr cpdb = Marshal.AllocHGlobal(0);
PlayerDatabase_API.DB_Init(new IntPtr(cpdb));
應該可以不用使用[out, ref]關鍵字了,所以宣告時也不用使用[out, ref]
------解决方案--------------------
你在C中定義的DBDisplay函數不是二重指針,所以只要寫成
Intptr c2 = Marshal.AllocHGlobal(0);
PlayerDatabase_API.DBDisplay(c2);
即可。
當然,你可以不用重覆定義Intptr c2 = Marshal.AllocHGlobal(0);
你可以使用原有的IntPtr cpdb = Marshal.AllocHGlobal(0);
即可。
引用:
建议你把 void **DB 直接定义成 int,然后内部强制转换试试看。
應該是指在你寫的C代碼(API)中,將
void DB_Init(void **DB)
{
CPlayerDatabase *myDB = new CPlayerDatabase();
myDB->init();
*DB = myDB;
}
改成
int DB_Init(void **DB)
{
.....
return ....
}
這樣你在平台調用時就可以用你原來的方式,且用int來宣告變數即可。(我猜的啦﹗)