日期:2014-05-17  浏览次数:20835 次

C# 调用C++ 动态链接库 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
#define DllExport _declspec(dllexport)
extern "C" DllExport int __stdcall ConnectReader (HANDLE &hPort, int nTransMode,int nNetPort,LPCTSTR strReaderIP,LPCTSTR strSerialNum,int nBaudRate = 115200);

这个是C++项目中的调用
hComHandle=INVALID_HANDLE_VALUE;
int status = ConnectReader(hComHandle, workmode,netport,strIp,CommPort[i],nBaudRate);
可以正常调用

我在C#中 的引用
[DllImport(m_strPath)]
        public static extern int ConnectReader(IntPtr handle, int nTransMode, int nNetPort, String strReaderIP, String strSerialNum, int nBaudRate);
C#调用
IntPtr handle = IntPtr.Zero;
int ks = GetAPI.ConnectReader(handle, 1, 0, "192.168.1.1", "COM2",19200);

直接过不了--尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
C#

------解决方案--------------------
HANDLE &hPort  

=>

ConnectReader(ref IntPtr handle
------解决方案--------------------
String换成StringBuilder看看。
------解决方案--------------------
引用:
HANDLE &hPort  

=>

ConnectReader(ref IntPtr handle

在C#里面,地址是不能引用传递的。那样写肯定不行,我自己写C++玩过,通不过。

IntPtr handle = IntPtr.Zero;这句错了,你要分配一个有缓存空间给它,而不是一个无效的地址。
例如:
byte[] buffer = new byte[65536];//申请65536大小的一个缓存区
GCHandle gc = GCHandle.Alloc(buffer, GCHandleType.Pinned);//gc固定对象地址
IntPtr handle = GCHandle.ToIntPtr(gc);//获取固定的对象地址
//做你要的事情

            
gc.Free();//释放gc