我正在使用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 ++的专家,所以非常感谢任何提示。谢谢!
答案 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内容。
祝你好运。