与c ++中的typedef变量对话

时间:2015-01-26 06:30:21

标签: c# c++ variables dll typedef

我有像这样的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!

2 个答案:

答案 0 :(得分:0)

&g_screen_node用于将g_screen_node的地址传递给InitNode函数。这通常意味着该参数将用作输出参数。

至于您收到错误代码的原因,我会采取措施,并要求BBIA.CB_initNode需要&ab,而不是ab

答案 1 :(得分:0)

按顺序回答问题的部分:

  1. 您应该参考InitNode的文档(或源代码,如果没有可用的文档)来了解InitNode的输入和输出参数的含义。 最有可能方法分配并初始化一个ScreenNode并向调用者返回一个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中,将返回的指针定义为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);
    
  5. 然后,如果您需要将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之前告诉我们您呼叫的功能,如果有的话