首页 新闻 会员 周边

c#调用c++dll遇到的问题。

0
悬赏园豆:5 [已解决问题] 解决于 2010-08-17 09:13

一直都觉得c#调用c++dll这块很麻烦,不过要用也没办法。刚开始类型转换头疼了一阵,不过也都解决了,今天遇到的这个问题,是怎么都过不去了,希望大家指点指点!

C++原型: 

struct SipClient
{
char * realm;
void * lpvoid;

char * from_ip;
int from_port;
char * to_ip;
int to_port;

char * client_id;
char * server_id; //平台编码

int reg_count;


SipClient(){memset(
this, 0, sizeof(SipClient));}
~SipClient()
{
delete[] from_ip;
delete[] realm;
delete[] client_id;
delete[] to_ip;
delete[] server_id;
}
};

SIPCLIENT_API SipClient
* SCInit(const char * reaml, const char * from_ip, int from_port, const char * to_ip, int to_port, const char * server_id, const char * user_id, const char * user_name, void * user_obj_param);

C#里是这么些的

public struct SipClient
{
public string realm; //鉴权码
public IntPtr lpvoid; //用户参数
public string from_ip; //本地IP
public int from_port; //本地端口
public string to_ip; //SIP服务器IP
public int to_port; //SIP服务器端口
public string client_id; //用户的编码
public string server_id; //SIP服务器的编码
public int reg_id; //保留,暂不使用
}

[DllImport(
"sipclient.dll")]
public static extern SipClient SCInit(string reaml, string from_ip, int from_port,
string to_ip, int to_port, string server_id,
string user_id, string user_name, IntPtr user_obj_param);
 
//函数调用
 private const string USER_ID = "180400000090000000";
 private const string SERVER_ID = "180400000099000000";

SIPCLIENT_API.SCInit("192.168.10.23", "192.168.10.32", 5092, "192.168.10.23", 5090, SERVER_ID, USER_ID, USER_ID, IntPtr.Zero);

 

黄色标记处写作SipClient时,运行时函数调用异常:

Additional information: 方法的类型签名与 PInvoke 不兼容。

想按照网上一种做法,将SipClient改为IntPtr,运行时还是出错,不过异常是:

Additional information: 无法在 DLL“sipclient.dll”中找到名为“SCInit”的入口点。

我能够想到的办法都用了,还是不能解决这些问题,期待大家的回答!

peony007的主页 peony007 | 菜鸟二级 | 园豆:397
提问于:2010-08-13 17:26
< >
分享
最佳答案
0

用 DEPENDS.EXE 查看你的 sipclient.dll 中的函数的导出名称,它有可能的名称是 SCInitXAjlkjsaldjaslkd.

生成 C++ DLL的时候,用 extern "C" 导出函数名称,则可以避免编译器为你自动生成的名称。

 

调用成功后,你可以用 Marshal.PtrToStructure 把 IntPtr 转换成你的 SipClient。

收获园豆:4
Launcher | 高人七级 |园豆:45045 | 2010-08-13 17:33
同事用一个什么文件把所有函数名指定了一下,c++的东西我也不太懂,不过道理是跟答案一样,还是导出函数的问题!
peony007 | 园豆:397 (菜鸟二级) | 2010-08-17 09:16

用.def 模块定义文件,定义导出函数的名称。

专注一点 | 园豆:200 (初学一级) | 2013-09-13 13:51
其他回答(1)
0

确保C#编译出来的EXE和你的DLL都是32位或者64位的。

mixed 的exe会自动识别和提升intptr的长度,在32位系统下是32位的,在64位系统下是64位的,针对这个,需要做两个DLL,一个32位,一个64位。

收获园豆:1
侦探在线 | 园豆:206 (菜鸟二级) | 2010-08-13 23:28

那C#程序在调用64位的DLL时,需要具体注意些什么呢

支持(0) 反对(0) 专注一点 | 园豆:200 (初学一级) | 2013-09-13 13:49
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册