如何在C 调用的VB.NET中编写回调函数
How to write a callback function in VB.NET called from C++
我正在使用由文档提供的外部源提供的C 编写的DLL,但没有源代码。
在某些情况下,我需要在vb.net中实例化回调函数,该回调函数应由C 模块调用。提供的文档看起来像;
函数我致电以建立回电;
extern "C" int EDIT_API Do_RunStuff(
const int MyID,
const char* my_tag1,
const char* my_tag2,
const char* some_data,
const int some_options,
int* some_count,
void* owner,
void* callback_func);
呼叫函数的模板是
typedef void (*CallbackRunStuff)( void* ptr2object, const char* my_tag1,
const char* my_name, const char* some_code,
const char* error_type, const char* message );
所以我创建了我的vb.net代码;
声明函数;
Declare Function Do_RunStuff Lib "SOME.DLL" (ByVal MyID As Integer, _
ByVal my_tag1 As String, _
ByVal my_tag2 As String, _
ByVal some_data As String, _
ByVal some_options As Integer, _
ByRef some_count As Integer, _
ByRef owner As IntPtr, _
ByRef callback_func As IntPtr) As Integer
调用函数;
Dim objEditsErrorHandler As New editsErrorHandlerDelegate(AddressOf editsErrorHandler)
Dim objThis As GCHandle = GCHandle.Alloc(Me)
Dim ptrEditsErrorHandler As IntPtr = Marshal.GetFunctionPointerForDelegate(objEditsErrorHandler)
Dim ptrThis As IntPtr = GCHandle.ToIntPtr(objThis)
intResult = Do_RunStuff(_AnID, strTag1, strTag2, strSomeData, someValue, SomeCount, ptrThis, ptrEditsErrorHandler)
创建委托;
Public Delegate Sub editsErrorHandlerDelegate(ByRef objThis As IntPtr, ByVal strEditTag As String, ByVal strEditName As String, ByVal strAdminCode As String, ByVal strErrorType As String, ByVal strMessage As String)
创建功能;
Public Sub editsErrorHandler(ByRef objThis As IntPtr, ByVal strEditTag As String, ByVal strEditName As String, ByVal strAdminCode As String, ByVal strErrorType As String, ByVal strMessage As String)
Debug.Print("*****====================*****")
Debug.Print("Error Type: " & strErrorType)
Debug.Print("Message: " & strMessage)
End Sub
当不需要回调时,一切都可以游泳。当它试图拨打editsErrorHandler
的电话中,该程序中止;
中出现了" system.AccessvioLationException"类型的例外
我不知道从这里去哪里。DLL的开发人员是C 的人,没有答案。
有什么想法?
编辑1
在文档中,他们显示了如何从C 呼叫
致电可能会回电的模块;
FMyEngineClass->Do_RunStuff(my_tag1, my_tag2, some_data,
some_options, &some_count, this, ShowErrorMessages);
称为返回的函数的定义;
static void ShowErrorMessages(void* caller, const char* my_tag1,
const char* some_name, const char* some_code,
const char* error_type, const char* message)
好吧,如果其他人发现这一点,我的特殊问题是一条愚蠢的行;
<UnmanagedFunctionPointer(CallingConvention.Cdecl)>
需要立即前进;
Public Delegate Sub editsErrorHandlerDelegate(ByRef objThis As IntPtr, ByVal strEditTag As String, ByVal strEditName As String, ByVal strAdminCode As String, ByVal strErrorType As String, ByVal strMessage As String)
喜欢;
<UnmanagedFunctionPointer(CallingConvention.Cdecl)>
Public Delegate Sub editsErrorHandlerDelegate(ByRef objThis As IntPtr, ByVal strEditTag As String, ByVal strEditName As String, ByVal strAdminCode As String, ByVal strErrorType As String, ByVal strMessage As String)
您不需要明确使用GCHandle
来传递功能指针,我严重怀疑您的API声明正确(您似乎已经摆脱了要使用您错了的参数(。
我相信以下内容是正确的:
<UnmanagedFunctionPointer(CallingConvention.Cdecl)> _
Public Delegate Sub editsErrorHandlerDelegate(ByVal objThis As IntPtr, <[In]()> ByVal strEditTag As String, <[In]()> ByVal strEditName As String, <[In]()> ByVal strAdminCode As String, <[In]()> ByVal strErrorType As String, <[In]()> ByVal strMessage As String)
Declare Function Do_RunStuff Lib "SOME.DLL" (ByVal MyID As Integer, _
ByVal my_tag1 As String, _
ByVal my_tag2 As String, _
ByVal some_data As String, _
ByVal some_options As Integer, _
ByRef some_count As Integer, _
ByVal owner As WhateverClassThisResidesIn, _
ByVal callback_func As editsErrorHandlerDelegate) As Integer
Public Sub editsErrorHandler(ByVal objThis As IntPtr, ByVal strEditTag As String, ByVal strEditName As String, ByVal strAdminCode As String, ByVal strErrorType As String, ByVal strMessage As String)
Debug.Print("*****====================*****")
Debug.Print("Error Type: " & strErrorType)
Debug.Print("Message: " & strMessage)
End Sub
Do_RunStuff(_AnID, strTag1, strTag2, strSomeData, someValue, someCount, Me, AddressOf editsErrorHandler)
如果WhateverClassThisResidesIn
是一种结构,则需要是ByRef owner As ThatStructure
。
相关文章:
- 架构决策:返回std::future还是提供回调
- 正在为Xtensa simcall函数编写回调函数
- 如何在C++中使用非静态成员函数作为回调函数
- FLTK:按下哪个按钮 - 将数字传递给按钮的回调 (lambda)
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 用于在回调中调用解析器的设计模式
- 如何使用C++对象的成员函数作为 C 样式回调?
- Java从C++回调到C++回调
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- 从不同的 cpp 调用回调函数会导致bad_function_call
- pcap_handler回调仅在使用 NPCAP v0.9991 时包含空数据包
- 不带轮询的 SDL2 事件回调
- C++存储带有可变参数的回调
- 如何使用 Node-addon-API 实现 node-nan 回调
- 处理影响跨不同线程共享对象的定时回调的最佳方法是什么?
- 访问类C++ C 样式回调
- 处理类内的回调时,必须调用对非静态成员函数的引用
- 如果 C 函数仍然可以间接执行(通过回调函数),那么将它声明为静态函数是否是一种不好的做法?
- 在C++中实现回调
- C++ 事件管理器的回调,使用 std::function 和 std:bind 以及派生类作为参数