简介:使用C#和C++联合编程时,常常要在C#和C++语言之间来回切换,对于现在的我来说很容易出错,在这里记录一下。附上常用C#和C++的数据类型对应。
1.错误信息:
System.AccessViolationException
HResult=0x80004003
Message=尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
image.png
2. 原因:
网上搜索一番,发现这个问题在使用C#调用C++dll 文件时很容易发生,一般就是参数传递或者参数返回时出现问题,最多的是数据类型不匹配。
本来昨天还好好的程序,今天改了一点就彻底去世,抓掉50根头发后突然想到C#和C++的数据类型对应问题。仔细已检查就是这里了。
- C# code
[DllImport("match.dll", CallingConvention = CallingConvention.Cdecl)]
extern unsafe static int TemplateModel(ref BmpData tempBmp, int channel, int range, string key);
- C++ code
extern "C" _declspec(dllexport) int TemplateModel(BmpData tempBmp, int channel, int range, std::string key)
最后一个参数 是C#传递一个string变量到C++ 函数,在C++里面我用的接受参数是std::string,但是真正的对应应该是C#的string 对应C++中的char *。那最后就很明显了,把std::string 换成 char *,最后再把char *转为std::string,问题也就解决了。
extern "C" _declspec(dllexport) int TemplateModel(BmpData tempBmp, int channel, int range, char * modelKey)
{
std::string key = modelKey;
........
}
附录:C#和C++的数据类型对应
C++ Type | C# Type | Size |
---|---|---|
BOOL | bool | 1 byte |
BYTE | byte | 1 byte |
CHAR | byte | 1 byte |
DECIMAL | Decimal | 16 bytes |
DOUBLE | double | 8 bytes |
DWORD | uint, UInt32 | 4 bytes |
FLOAT | float, single | 4 bytes |
INT, signed int | int, Int32 | 4 bytes |
INT16, signed short int | short, Int16 | 2 bytes |
INT32, signed int | int, Int32 | 4 bytes |
INT64 | long, Int64 | 8 bytes |
LONG | int, Int32 | 4 bytes |
LONG32, signed int | int, Int32 | 4 bytes |
LONG64 | long, Int64 | 8 bytes |
LONGLONG | long, Int64 | 8 bytes |
SHORT, signed short int | short, Int16 | 2 bytes |
UCHAR, unsigned char | byte | 1 byte |
UINT, unsigned int | uint, UInt32 | 4 bytes |
UINT16, WORD | ushort, UInt16 | 2 bytes |
UINT32, unsigned int | uint, UInt32 | 4 bytes |
UINT64 | ulong, UInt64 | 8 bytes |
ULONG, unsigned long | uint, UInt32 | 4 bytes |
ULONG32 | uint, UInt32 | 4 bytes |
ULONG64 | ulong, UInt64 | 8 bytes |
ULONGLONG | ulong, UInt64 | 8 bytes |
WORD | ushort | 2 bytes |
void*, pointers | IntPtr | x86=4 bytes, x64=8 bytes |
网友评论