在 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

按顺序回答问题的各个部分:

  1. 您应该查阅InitNode的文档(或源代码,如果没有文档可用)以了解InitNode的输入和输出参数的含义。 很可能该方法实际上分配并初始化一个ScreenNode和returns一个opaque pointer给调用者- - 一个内部实现被隐藏的。但是,您的问题中没有足够的信息来确定这一点。

    我对你问题其余部分的回答假定这是真的。如果没有,请使用 InitNode 中的适当文档更新您的问题,然后我们可以再减少一次回答。

  2. 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()中设置的指针值传出

  3. 然后在你的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);
    
  4. 然后在主程序中:

    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 之前让我们知道您调用的是什么函数,如果有的话。