将指针传递给VB中的DLL中的extern C函数

Wes*_*ler 5 c++ vb.net dll

我是一名C++(MSVC)作家,VB新手试图协助一位刚刚未完成此任务的专家VB.net作家.

我们希望开发C/C++和VB应用程序,以使用C++编写的带有C外部API函数的DLL.C++程序运行得很好.这是我们遇到困难的VB.

DLL提供了一个extern C功能:

RegisterCallback( void* cbFuncPtr, void* dataPtr );
Run Code Online (Sandbox Code Playgroud)

注1:请参阅下面的注释,了解设计变更以及我们制作的原因.

注2:附加更新作为下面的答案添加.

回调函数有哪个C typedef:

typedef   (void)(* CALL_NACK)(void*);
Run Code Online (Sandbox Code Playgroud)

cbFuncPtr预期是一个函数指针,一些VB函数将被调用为CALL_BACK.它dataPtr是指向具有此C定义的数据结构的指针:

typedef struct 
{
   int      retCode;
   void*    a_C_ptr;
   char     message[500];
}  cbResponse_t;
Run Code Online (Sandbox Code Playgroud)

其中a_C_ptr is an internal pointer in the DLL that the VB can cast tolong`.它唯一地标识DLL中回调的位置,并允许VB函数识别来自相同/不同位置的调用.

我们能够RegisterCallback()很好地从VB 访问和运行该函数.记录显示我们到达那里并且数据被传入.实际数据似乎是问题所在.

在阅读大约一百万个论坛条目时,我们了解到VB不知道什么是指针,VB结构不仅仅是有组织的内存.我们非常确定VB结构的"地址"不是C认为的地址.我们已经多次提到"编组"和"托管数据",但缺乏足够的理解来了解这些信息.

我们应该如何编写VB来为DLL提供其回调函数的执行地址?我们如何编写DLL可以填充的VB结构,就像它对C++一样?

我们可能需要一个DLL函数,其中调用应用程序可以说"C"或"VB"并且DLL处理结构指针的方式不同吗?如果是这样,如何编写C来填充VB结构?

Wes*_*ler 1

这有点太大和太深了,不能只是对原始帖子的编辑......

从@DaveNewman 发布的链接中,我提取了这个 gem:


这里有一些关于紧凑框架的信息,但在成人框架中也是一样的:

.NET Compact Framework 支持自动封送包含简单类型的结构和类。所有字段按照它们在结构或类定义中出现的顺序按顺序排列在内存中。类和结构在本机代码中都显示为指向 C/C++ 结构的指针。

托管堆中的对象可以随时由垃圾收集器在内存中移动,因此它们的物理地址可能会更改,恕不另行通知。P/Invoke 在每个方法调用期间自动固定通过引用传递的托管对象。这意味着传递给非托管代码的指针对于该一次调用将是有效的。请记住,不能保证该对象不会在后续调用中移动到不同的内存地址。

http://msdn.microsoft.com/en-us/library/aa446538.aspx#netcfmarshallingtypes_topic6


这是RegisterCallback( fcnPtr, dataPtr)函数的主要障碍。在注册时传入的指针可能随时更改,而RegisterCallback()不是当前语句。发帖者是这样总结的

您无需执行任何操作,因为结构会在调用期间自动固定。

当然,这意味着没有被固定在通话之外。

出于这个原因,我们决定对设计进行更改,将响应结构内置到 DLL 的 C/C++ 世界中,而不是 VB 的空间中。这样它就会保持原状。实际的回调函数的签名将保持不变,因此 VB 程序可以知道 DLL 将响应放在哪里。这还允许 DLL 中的响应程序为不同的需求分配单独的响应结构。