C#调C++写的DLL函数,出现“方法的类型签名与PInvoke不兼容错误”

mrpeterchen 2010-03-08 10:13:15
C++dll函数代码如下:

结构体原形:
typedef struct MY_DATA
{
int DataFlag;
char *DataBuff;
} MY_DATATYPE;

结构体变量声明赋值:
MY_DATATYPE msd;
msd.DataFlag = MY_EMPTY;
msd.DataBuff = (char*)malloc(MYTMPBUFFSIZE*sizeof(char));
ZeroMemory(msd.DataBuff,MYTMPBUFFSIZE*sizeof(char));

导出函数原形:

MY_DATATYPE SendBuffTo()
{
return msd;
}
×××××××××××××××××××××××××××××××××××××××××××××××××××××

C#中结构体定义代码:
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]
public struct MY_DATA
{
public Int32 Flag;
public String buff;
};

相应导出函数的委任声明:
public delegate MY_DATA SendBuffTo();

我只列出了问题代码段,因为C#中loadlibrary,getprocaddress都是好的,直到调GetDelegateForFunctionPointer这报错了;

C#委任代码原形:
public static Delegate GetDelegateFromInt(int address, Type t)
{
if (address == 0)
return null;
else
{
try
{
return Marshal.GetDelegateForFunctionPointer(new IntPtr(address), t);
}
catch (Exception e)
{
Console.WriteLine(e);

return null;
}
}
}

C#中调用此委任函数如下:
SendBuffTo sbt = (SendBuffTo)DllWrap.GetDelegateFromInt(FunSenBuf, typeof(SendBuffTo));

网上说的类型基本都试了,哭啊,都不行,太恶心了,哪位大侠救救我啊。。。
...全文
586 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
zqs1002 2011-08-14
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 mrpeterchen 的回复:]
哈哈多谢指教:

总算在前辈的细心指点下:

我又搜了些综合办法,把问题解决了,下面介绍我的解决办法:

首先改C#结构体如下:

public struct MY_DATA
{
public int DataFlag;
public IntPtr Databuff;//注意,我并非将委托的类型改为IntPtr,而将string类结构成员变量改为IntPtr;
……
[/Quote]

我也遇到了同样的问题,折腾了一天,看到此贴,终于解决了问题 。就是下面这句:
string str = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(mssd.Databuff);
mrpeterchen 2010-03-09
  • 打赏
  • 举报
回复
哈哈多谢指教:

总算在前辈的细心指点下:

我又搜了些综合办法,把问题解决了,下面介绍我的解决办法:

首先改C#结构体如下:

public struct MY_DATA
{
public int DataFlag;
public IntPtr Databuff;//注意,我并非将委托的类型改为IntPtr,而将string类结构成员变量改为IntPtr;
};

委任代码不变:
public delegate MY_DATA SendBuffTo();

调用代码也不变:
SendBuffTo sbt = (SendBuffTo)DllWrap.GetDelegateFromInt(FunSenBuf, typeof(SendBuffTo));

mssd = sbt();//首先将C++的函数返回值读出,mssd是我声明过的C#中MY_DATA结构体变量;
string str = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(mssd.Databuff);//关键语句:将之前定义的IntPtr成员变量 Buff转换下,试过UNICODE,翻出来是问号,ANSI正确;
Console.WriteLine(str);
Console.WriteLine(mssd.DataFlag);//最后经过打印语句检验,值完全收到并解析成功;

再次感谢大侠的支持啊,小弟拜谢ING~~~~

感动死了,总算解决了。啊。。哈哈哈哈哈~~~
希望对遇到同样问题的人有帮助。。
xingyuebuyu 2010-03-09
  • 打赏
  • 举报
回复
MY_DATA md=new MY_DATA();
md=(MY_DATA)System.Runtime.InteropServices.Marshal.PtrToStructure(i, typeof(MY_DATA));


md就是你想返回的结构体,i是你调用DLL返回的指向一个MY_DATA结构体的指针
,是IntPtr类型的

因为这个DLL返回的是一个结构体,而这个结构体的大小是大于你所使用的INT,DOUBLE类型的大小,一旦你使用的大小超过这个结构体的大小就会报错的
mrpeterchen 2010-03-09
  • 打赏
  • 举报
回复
这样能调用成功,我试过INT,DOUBLE,都可以调用成功呢,哈奇怪,我返回类型明明不对也能调用成功
为什么啊

那我怎么得到结构体变量的值啊??

还请再赐教呢。。。


xingyuebuyu 2010-03-08
  • 打赏
  • 举报
回复
http://topic.csdn.net/u/20100308/16/ef639120-ae8c-41f5-9d5d-e9b57e17a302.html

public delegate IntPtr SendBuffTo();
这样看调用是否成功

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧