【问题标题】:Passing a pointer to a function in a DLL将指针传递给 DLL 中的函数
【发布时间】: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 指向的元素数。
  • 您可能还对this article related to NXCOMPAT and DEP感兴趣。
  • 也许你应该向我们展示错误的方法而不是调用它的方法......
  • @hmjd msg 数组的第二个字节包含消息的长度,传递的 msglenth 目前用于调试,我认为它将在最终代码中删除。 (我删除了调试 printf 函数 :))
  • @Tobias 最后一个加载的 DLL 是从其他代码测试的,工作正常,不幸的是。

标签: c# c++ c pointers dll


【解决方案1】:

好的,问题解决了,错误比我想象的要明显得多:_SendFunc(...) 的返回值不是int 而是long,这导致了上面的消息。

对不起,也感谢大家的帮助。

【讨论】:

  • 你确定这是唯一的原因吗? AFAIK 即使在 Win64 上 int 和 long 都是 32 位的,并且这两种类型都在同一个处理器寄存器中返回,所以混淆 int 和 long 实际上应该是 Windows 上的“你可以避免的错误”。
  • 是的,我敢肯定,纠正 int "status" var 以长期解决它,虽然我的想法和你一样。
  • 我同意 Wolfgang 的意见...在 Windows 上从 int 更改为 long 不能成为解决方案。注意调用约定不匹配:UssSend 的原型是什么?是__cdecl 还是__stdcall
  • Guy 它确实解决了它 :) 真的。即使它缺乏任何合乎逻辑的理由。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-02
  • 2012-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多