尝试使用外部库中的方法时出现 Read/Write 访问错误
Getting Read/Write access error when trying to use method from external library
我正在尝试使用库中的以下实现
C++
int CALLBACK xCallback(long xmitlen, int buflen, char *buf, long flen)
{
return 0;
}
extern "C" __declspec(dllexport) int __stdcall TXFIlestransfer(int port, string fileName);
__declspec(dllexport) int __stdcall TXFIlestransfer(int port, string fileName)
{
int ret;
char *test = &fileName[0];
ret = sio_FtKermitTx(port, test, xCallback, 27);
return ret;
}
我正在导入它以与 C# 一起使用并得到 System.AccessViolationException:'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'
如能帮助解决此错误,我们将不胜感激。
我通过在我的 C++ dll (Mydll.dll) 中模拟 sio_FtKermitTx
函数来测试你的程序:
int sio_FtKermitTx (int port, char *fname, int (CALLBACK *func) (long xmitlen, int buflen, char *buf, long flen), int key)
{
return 5;
}
即使是空的body,我也遇到了和你一样的问题
经过多次调查,我注意到问题出在我们在 C#
和 C++
代码之间使用了 string
object 代码,出于一个原因或另一个(例如 unicode / 多字节配置,或者仅仅是因为难以实现共享复杂的 objects)导致问题。
解法:
通过将 string
object 替换为原始 char
类型,一切正常:
C#代码:
using System.Runtime.InteropServices;
namespace MyProgramme
{
class Test
{
// Import C++ DLL
[DllImport("Mydll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int TXFIlestransfer(int i, char[] filename);
//public static extern int TXFIlestransfer(int i, string filename); // this crash
static void RunTest(/*LoadFilterEVENTMessage msg*/)
{
string c = "ABC";
char[] char_arr = c.ToCharArray();
int i = TXFIlestransfer(3, char_arr);
// int i = TXFIlestransfer(3, c); string version crash
string s = i.ToString();
MessageBox.Show(s);
}
/* Methods in DLL being used below */
public static void Main()
{
RunTest();
}
};
}
C++ DLL 代码(Mydll.dll):
extern "C" __declspec(dllexport) int TXFIlestransfer(int port, char fileName[])
{
int ret;
char *test = &fileName[0];
ret = sio_FtKermitTx(port, test, xCallback, 27);
return ret;
}
无论如何,您的 sio_FtKermitTx
函数在参数中接受 char*
,因此将您的 TXFIlestransfer
参数从 string
更改为 char[]
没有问题。
结果:
在 运行 C# 程序之后你会得到这个:
我正在尝试使用库中的以下实现
C++
int CALLBACK xCallback(long xmitlen, int buflen, char *buf, long flen)
{
return 0;
}
extern "C" __declspec(dllexport) int __stdcall TXFIlestransfer(int port, string fileName);
__declspec(dllexport) int __stdcall TXFIlestransfer(int port, string fileName)
{
int ret;
char *test = &fileName[0];
ret = sio_FtKermitTx(port, test, xCallback, 27);
return ret;
}
我正在导入它以与 C# 一起使用并得到 System.AccessViolationException:'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'
如能帮助解决此错误,我们将不胜感激。
我通过在我的 C++ dll (Mydll.dll) 中模拟 sio_FtKermitTx
函数来测试你的程序:
int sio_FtKermitTx (int port, char *fname, int (CALLBACK *func) (long xmitlen, int buflen, char *buf, long flen), int key)
{
return 5;
}
即使是空的body,我也遇到了和你一样的问题
经过多次调查,我注意到问题出在我们在 C#
和 C++
代码之间使用了 string
object 代码,出于一个原因或另一个(例如 unicode / 多字节配置,或者仅仅是因为难以实现共享复杂的 objects)导致问题。
解法:
通过将 string
object 替换为原始 char
类型,一切正常:
C#代码:
using System.Runtime.InteropServices;
namespace MyProgramme
{
class Test
{
// Import C++ DLL
[DllImport("Mydll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int TXFIlestransfer(int i, char[] filename);
//public static extern int TXFIlestransfer(int i, string filename); // this crash
static void RunTest(/*LoadFilterEVENTMessage msg*/)
{
string c = "ABC";
char[] char_arr = c.ToCharArray();
int i = TXFIlestransfer(3, char_arr);
// int i = TXFIlestransfer(3, c); string version crash
string s = i.ToString();
MessageBox.Show(s);
}
/* Methods in DLL being used below */
public static void Main()
{
RunTest();
}
};
}
C++ DLL 代码(Mydll.dll):
extern "C" __declspec(dllexport) int TXFIlestransfer(int port, char fileName[])
{
int ret;
char *test = &fileName[0];
ret = sio_FtKermitTx(port, test, xCallback, 27);
return ret;
}
无论如何,您的 sio_FtKermitTx
函数在参数中接受 char*
,因此将您的 TXFIlestransfer
参数从 string
更改为 char[]
没有问题。
结果:
在 运行 C# 程序之后你会得到这个: