在 C++ 中与 typedef 变量的对话
conversation with typedef variable in c++
我有这样的 C++ 类型定义
typedef void* ScreenNode;
并像这样在我的 C++ 代码中使用它
ret = InitNode("factory", &g_screen_node, 128, 128, EN_C1Dev);
**EN_C1Dev 是一个枚举
我的 typedef 变量是一个空指针和 InitNode return 一个通过改变指针值 "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 定义class
[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 函数 return 错误代码和 g_screen_node 不是 return 预期值并保持在 0x00000000!
&g_screen_node
用于将g_screen_node
的地址传递给InitNode
函数。这通常意味着该参数将用作输出参数。
至于您收到错误代码的原因,我会试探一下,您对 BBIA.CB_initNode
的调用需要 &ab
,而不是 ab
按顺序回答问题的各个部分:
您应该查阅InitNode
的文档(或源代码,如果没有文档可用)以了解InitNode
的输入和输出参数的含义。 很可能该方法实际上分配并初始化一个ScreenNode
和returns一个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, you define the returned pointer as an 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
之前让我们知道您调用的是什么函数,如果有的话。
我有这样的 C++ 类型定义
typedef void* ScreenNode;
并像这样在我的 C++ 代码中使用它
ret = InitNode("factory", &g_screen_node, 128, 128, EN_C1Dev);
**EN_C1Dev 是一个枚举
我的 typedef 变量是一个空指针和 InitNode return 一个通过改变指针值 "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 定义class
[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 函数 return 错误代码和 g_screen_node 不是 return 预期值并保持在 0x00000000!
&g_screen_node
用于将g_screen_node
的地址传递给InitNode
函数。这通常意味着该参数将用作输出参数。
至于您收到错误代码的原因,我会试探一下,您对 BBIA.CB_initNode
的调用需要 &ab
,而不是 ab
按顺序回答问题的各个部分:
您应该查阅
InitNode
的文档(或源代码,如果没有文档可用)以了解InitNode
的输入和输出参数的含义。 很可能该方法实际上分配并初始化一个ScreenNode
和returns一个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, you define the returned pointer as an
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
之前让我们知道您调用的是什么函数,如果有的话。