【发布时间】:2012-01-26 10:16:51
【问题描述】:
我遇到了一个严重的问题。我有 C# 代码加载用 C 编码的 DLL,该 DLL 调用用 C++ 编码的 DLL。一切都很好,直到我想将数组的指针从 C 级别传递到 C++ 级别。
C中的调用代码如下:
#include <windows.h>
#include <winbase.h>
#include <windef.h>
int sendDLL( int* , int );
typedef int (*SendFunc)(int*);
int sendDLL( int* msg , int msgLength )
{
int status = 0;
SendFunc _SendFunc;
HINSTANCE serialLibrary = LoadLibrary("sender.dll");
if (serialLibrary)
{
_SendFunc = (SendFunc)GetProcAddress(serialLibrary, "UssSend");
if (_SendFunc)
{
status = _SendFunc(msg);
}
FreeLibrary(serialLibrary);
}
return status;
}
现在真正的转折是仅传递指针是不够的:传递的消息将在 DLL 中被覆盖,我们需要再次读取它,直到 _SendFunc(...) 返回。
如果我从 Visual Studio 启动程序(最高级别 - C#),我会在调用 status = _SendFunc=(msg); 时得到以下正确信息(这是肯定的,如果注释掉,则不会发生错误。)
TestRS232.exe 中出现“System.AccessViolationException”类型的未处理异常
附加信息:试图读取或写入受保护的内存。这通常表明其他内存已损坏。
有办法解决吗?
【问题讨论】:
-
UssSend()如何知道msg指向的数组的大小?serialDLL()采用msgLength参数,该参数(大概)是msg指向的元素数。 -
也许你应该向我们展示错误的方法而不是调用它的方法......
-
@hmjd msg 数组的第二个字节包含消息的长度,传递的 msglenth 目前用于调试,我认为它将在最终代码中删除。 (我删除了调试 printf 函数 :))
-
@Tobias 最后一个加载的 DLL 是从其他代码测试的,工作正常,不幸的是。