读书人

C#调用C++DLL解决方法

发布时间: 2013-06-25 23:45:41 作者: rapoo

C#调用C++DLL
先有C++结构体
typedef struct
{
uint8 start_byte;//0x2
uint8addr;
uint8update_byte;//0x35
uint8type;//software or font
chardata_length[8];
chars_data_pack_sn[8];
uint8data[512];
uint8end_byte;//0x3
uint8check_sum1;
uint8check_sum2;
}update_soft_datapack_t;

我写的对应的C#结构体为
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct update_soft_start_t
{
public byte start_byte;//0x2
public byte addr;
public byte update_byte;//0x35
public byte type;//software or font
public byte first_or_second;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] // 大小为8
public char[] data_pack_num;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] // 大小为8
public char[] sw_length;
public byte end_byte;//0x3
public byte check_sum1;
public byte check_sum2;
}

用该结构体接收调用C++DLL中返回的值就会报错:
未处理的“System.Runtime.InteropServices.MarshalDirectiveException”类型的异常出现在 Demo.exe 中。
其他信息: 方法的类型签名与 PInvoke 不兼容。
代码如下:
C#


[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct update_soft_start_t
{
public byte start_byte;//0x2
public byte addr;
public byte update_byte;//0x35
public byte type;//software or font
public byte first_or_second;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] // 大小为8
public char[] data_pack_num;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] // 大小为8
public char[] sw_length;
public byte end_byte;//0x3
public byte check_sum1;
public byte check_sum2;


}


[DllImport("MFCDLL.dll", EntryPoint = "UpdateSoftStartFast")]
public static extern update_soft_start_t UpdateSoftStartFast(byte addr, System.UInt32 size_file);

private void btnCall_Click(object sender, EventArgs e)
{



update_soft_start_t message2 = new update_soft_start_t();

message2=UpdateSoftStartFast(Convert.ToByte(0x20),Convert.ToUInt32(86792));

}



C++

extern "C" __declspec(dllexport) update_soft_start_t* UpdateSoftStartFast(uint8 iLedAddr,uint32 size_file)
{

uint32 size_frame;

if(size_file%512)
size_frame = size_file/512+1;
else
size_frame = size_file/512;

//
//memset(&iUpdateInfo,0,sizeof(Updateing_Info));
iUpdateInfo.iPackNum = size_frame;
if(iUpdateInfo.iPackNum%10)
{

iUpdateInfo.iUpdateStep = iUpdateInfo.iPackNum/10+1;
}
else
{
iUpdateInfo.iUpdateStep = iUpdateInfo.iPackNum/10;
}

if(size_frame)
{
update_soft_start_t *message = (update_soft_start_t *)calloc(sizeof(update_soft_start_t)+1,sizeof(char));

if(message)
{
uint8 i, size,sum=0xff;

message->start_byte = 0x2;
message->addr = iLedAddr;
message->update_byte = 0x35;
message->type = 0x3a;
message->first_or_second = 0x30;
memset(message->data_pack_num,0x30,8);
sprintf(message->data_pack_num,"%d",size_frame);
memset(message->sw_length,0x30,8);
sprintf(message->sw_length,"%d",size_file);
message->end_byte = 0x3;

size= sizeof(update_soft_start_t)-2;

for(i = 0;i < size; i++)
{
sum ^= *((uint8 *)message+i);

}
message->check_sum1 = ((sum >> 4) & 0x0f) + 0x30;
message->check_sum2 = (sum & 0x0f) + 0x30;

return message;

free(message);

}
}

请高手帮忙 C++ C# struct
[解决办法]
C++和C#定义的结构体怎么不一样:

C++:
char data_length[8];
char s_data_pack_sn[8];


uint8data[512];

C#:
public byte first_or_second;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] // 大小为8
public char[] data_pack_num;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] // 大小为8
public char[] sw_length;
[解决办法]
C++ __stdcall
或者:
C# CallingConvention = Cdecl。
[解决办法]
可以参考下这个博客来实现试试:http://www.cnblogs.com/zhili/archive/2013/01/23/DataSend.html
C# 中调用C++ dll,主要是如何在C# 代码中定义定义对应的结构体类型的

读书人网 >C#

热点推荐