我有像这样的c ++类型定义
typedef void* ScreenNode;
并在我的c ++代码中使用它
ret = InitNode("factory", &g_screen_node, 128, 128, EN_C1Dev);
** EN_C1Dev是ENUM
我的typedef变量是一个void指针,InitNode通过改变指针值“g_screen_node”返回一个值。
现在我在具有此定义的C#程序中的dll中使用此函数
c ++代码
extern“C”__ declspec(dllexport)int CB_initNode(ScreenNode * p_g_screen_node,int width,int heigth,EN_DevType EN_C1Dev) { int ret = 0;
//InitNode ----------------------------------------------------------------
ret = InitNode("factory", p_g_screen_node, 128, 128, EN_C1Dev);
return ret;
}
dll定义类
[DllImport(dllName)]
public static extern
int CB_initNode(out IntPtr g_screen_node, int width, int heigth, EN_DevType EN_C1Dev);
最后是我的主程序
IntPtr g_screen_node = new IntPtr();
ret = BBIA.CB_initNode(out g_screen_node , 128, 128, EN_DevType.EN_C3Dev);
CB_initNode 函数返回错误代码而g_screen_node不返回预期值并保持在0x00000000!
答案 0 :(得分:0)
&g_screen_node
用于将g_screen_node
的地址传递给InitNode
函数。这通常意味着该参数将用作输出参数。
至于您收到错误代码的原因,我会采取措施,并要求BBIA.CB_initNode
需要&ab
,而不是ab
答案 1 :(得分:0)
按顺序回答问题的部分:
您应该参考InitNode
的文档(或源代码,如果没有可用的文档)来了解InitNode
的输入和输出参数的含义。 最有可能方法分配并初始化一个ScreenNode
并向调用者返回一个opaque pointer - 一个内部实现被隐藏的调用者。但是,您的问题中没有足够的信息来确定这一点。
我对你问题其余部分的回答都认为这是真的。如果没有,请使用InitNode
中的相应文档更新您的问题,然后我们可以采取另一种措施来回答。
c ++代码。您需要使用extern "C" __declspec(dllexport)
来装饰您的函数:
extern "C" __declspec(dllexport) int CB_initNode(ScreenNode *p_g_screen_node,int width,int heigth, EN_DevType EN_C1Dev)
{
int ret = 0;
//InitNode ----------------------------------------------------------------
ret = InitNode("factory", p_g_screen_node, 128, 128, EN_C1Dev);
return ret;
}
您还需要传入指向ScreenNode
的指针(即双指针),以便可以传达InitNode()
中设置的指针值。
然后在您的c#extern declaration中,将返回的指针定义为out IntPtr
:
[DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
public static extern int CB_initNode(out IntPtr g_screen_node, int width, int heigth, EN_DevType EN_C1Dev);
然后在主程序中:
IntPtr g_screen_node;
var ret = BBIA.CB_initNode(out g_screen_node, 128, 128, EN_DevType.EN_C3Dev);
然后,如果您需要将ScreenNode
传递回同一个库,则可以使用之前返回的IntPtr
。完成后,不要忘记释放它 - 大概你正在使用的库也有一种方法。
最后,您没有说明EN_DevType
是什么,但我猜它是enum
。如果是这样,您应该检查您是否具有正确的值。如果不是enum
,那么我的问题答案可能需要更新。
<强>更新强>
如果InitNode
需要知道传入的void **
指针的当前值,因为它已预先分配或预初始化,签名将如下所示:
[DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
public static extern int CB_initNode(ref IntPtr g_screen_node, int width, int heigth, EN_DevType EN_C1Dev);
IntPtr g_screen_node = // However you initialize are supposed to allocate it using your library, possibly just IntPtr.Zero.
var ret = BBIA.CB_initNode(ref g_screen_node, 128, 128, EN_DevType.EN_C3Dev);
为了让我们自信地回答而不是猜测,请使用InitNode
的文档更新您的问题,并在致电InitNode
之前告诉我们您呼叫的功能,如果有的话