需要帮助将c ++定义转换为c#等价物

时间:2010-08-31 18:06:43

标签: c# c++

我正在使用API​​(用c ++编写)连接到DVR机器,实际上我只有.dll和.lib文件,我想在.NET(C#)中完成这项工作。 因此,API doc包含dll中所有函数的定义,而我正在努力弄清楚如何将这些函数转换为等效的C#定义。其中一些是直截了当的,但有些我无法使其发挥作用。

例如,有这个功能:

bool searchEvent(int channel, const LONG* condition, bool next)  

在我的c#课程中,我提出以下内容:

[DllImport("search.dll")]  
protected static extern bool searchEvent(int channel,  
[MarshalAs(UnmanagedType.I8)]long condition, bool next);

但是当我调用searchEvent函数时,它会引发一个错误(内存错误),我猜是因为那个long var。所以我的问题是如何将“const LONG * condition”翻译成c#? 此外,该searchEvent函数触发返回结构的回调。我无法翻译该结构的某些变量,例如:

char _version[2]  
time_t _time  
BYTE* _minute  
unsigned short int _dwell[MAX]  

有人可以帮帮我吗?我不是c ++的专家,所以非常感谢任何提示。谢谢!

2 个答案:

答案 0 :(得分:1)

    [DllImport("search.dll")]
    [return: MarshalAs(UnmanagedType.U1)]
    private static extern bool searchEvent(
        int channel,
        ref int condition,
        [MarshalAs(UnmanagedType.U1)] bool next
    );

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    private struct Mumble {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]
        public string version;
        public long time;
        public IntPtr minute;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX)]
        public ushort _dwell[];
    }

您必须使用Marshal.ReadXxxx()自行封送Mumble.Minute值。这些声明对于互操作来说不是很好,建议用C ++ / CLI语言编写包装器。

答案 1 :(得分:0)

没有详细说明,你需要克服两个障碍: 1)由于您没有原始的.h(标题)文件,因此根据API文档猜测它可能是什么。希望你能做对,但是头文件中可能会有一些微妙的东西不会出现在文档中,比如结构打包,调用约定,名称修改等等。你可以先假设这个默认值东西。你必须尝试底线。

2)当您没有原始头文件时,您正在尝试将P / Invoke调用创建到C DLL中。你甚至不知道你是否知道如何从C进行这些调用,更不用说C#。

直接从C#执行此操作,您试图同时攻击这两个问题。当某些东西不起作用时,你不确定是不是因为你的P / Invoke语法错误,或者这是与你对头文件内容的解释有关的问题。我试着一次一个地攻击这些问题。首先,尝试从简单的C控制台应用程序进行DLL调用。这应该不难创建,然后手工构建.H文件,并且您可以进行所有调用。

完成后,您现在必须从C#开始调用这些调用。

坦率地说,我避免使用P / Invoke,除非我可以重用其他人创建的(来自http://PInvoke.net)用于Windows API。如果我是你,而且我已经新了如何从C调用,我只是为它创建一个C ++ / CLI包装器DLL。优点是,您可以像在控制台应用程序中一样完成呼叫 - 无需P / Invoke。然后将这些来自C ++ / CLI DLL的调用公开为.NET。您的C#代码将调用C ++ / CLI DLL,它看起来就像(并且是).NET组件,在C#代码中没有奇怪的P / Invoke内容。

祝你好运。