嘿所有我试图在c#中调用这个c ++函数:
BOOL __stdcall CodecStart(int hRadio,void __stdcall (*CallbackFunc)(void *),void *CallbackTarget);
这是来自此处的http://www.winradio.com/home/g305_sdk.htm的WinRadio api。
我确实发现其他人询问在网上调用这个特定的功能,他们有:
public delegate void CallbackFunc( IntPtr p);
[DllImport("WRG305API.dll")]
public static extern bool CodecStart(int hRadio, CallbackFunc func, IntPtr CallbackTarget);
但我无法弄清楚如何进一步实现这一点。
关于如何称呼它的任何想法或指导?
非常感谢答案 0 :(得分:4)
这是一个简单的实现,将它们放在一起。
class WinRadioWrapper
{
public delegate void CallbackFunc( IntPtr pData );
[DllImport( "WRG305API.dll" )]
public static extern bool CodecStart( int hRadio, CallbackFunc func, IntPtr CallbackTarget );
public bool CodecStartTest(int hRadio)
{
bool bStarted = CodecStart( hRadio, MyCallbackFunc, IntPtr.Zero );
return bStarted;
}
// Note: this method will be called from a different thread!
static void MyCallbackFunc( IntPtr pData )
{
// Sophisticated work goes here...
}
}
请注意,因为MyCallbackFunc
将在不同的线程上执行,所以我选择make static
。这样,您就不会想要访问WinRadioWrapper
数据成员。
为简单起见,我将IntPtr.Zero
参数传递给回调,但这可以指向您要在回调中使用的任何数据。
[请忽略此段] 如果您想将数据传递给回调,请查看Marshal.StructureToPtr
,但请确保固定您所拥有的数据重新传递,以确保它不被垃圾收集(有关详细信息,请参阅GCHandle
)。
修改强>
用svick的有趣词语(谢谢!),我意识到我正在混合一个复制的对象和一个固定的对象。
所以,要解决问题:
Marshal.StructureToPtr
。GCHandle
来 pin 它内存并防止它被垃圾收集。GCHandle
增加一些维护开销。答案 1 :(得分:0)
callback function是由执行某些功能的dll(在这种情况下,您正在导入)调用的代码。您还需要了解如何使用delegates in c#。您可以像这样实现代码:
public void MyCallback(IntPtr p)
{
//do something
}
然后你的dll电话会是这样的:
[DllImport("WRG305API.dll")]
public static extern bool CodecStart(int hRadio, func, IntPtr CallbackTarget);
如果您需要更多指导,请发布您要转换的代码的C ++版本,我们可以帮助您使用C#版本。
答案 2 :(得分:0)
您需要做的就是创建一个与您声明的委托的签名相匹配的c#函数。创建一个委托,保持对该委托的引用,使其不被垃圾收集,并以委托作为回调调用dll导入。
所以你会有这样的事情:
public void MyCallback(IntPtr P)
{
//do something
}
// somewhere else in your code
var cb = new CallbackFunc(MyCallback);
CodecStart(..., cb, ...);