如何在C#中设置或获取DLL库的参数?

时间:2017-03-29 18:38:50

标签: c# c++ variables winapi dllimport

我有C ++库(32位),我想在C#中加载和使用它。 DLL正在工作(打开连接,关闭连接和其他没有参数的方法)。问题是具有参数的C ++库的所有方法的意外结果。例如:

C ++库方法规范:

unsigned int WINAPI acqStatus (WORD& stat, WORD& err);
unsigned int WINAPI getStatus (double& time, TCHAR* data);

C#源代码(外部方法):

    [DllImport("DllName.dll")]
    public static extern uint acqStatus(ref ushort stat, ref uint err);

    [DllImport("DllName.dll")]
    public static extern uint getStatus(ref double time, ref StringBuilder data);

C#第一个方法示例(返回错误值,或者我犯了错误,将IntPtr转换为整数):

        ushort stat = 0;
        uint err = 0;

        TCPInterface.acqStatus(ref stat, ref err);

        // Result of stat is: 0x0003 or 0x0004
        // bad value 3 (expected is 0), bad value 4 (expected is 1) 

与另一种方法相同的情况,返回TCHAR *。结果是字符串(字节数组)。我不知道,我是如何从数据变量中获取字符串的。

        double time;
        StringBuilder data = new StringBuilder();

        getStatus(out time, out data);

        // Exception:
        An unhandled exception of type 'System.AccessViolationException' occurred in mscorlib.dll

        Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

我正在使用64位Windows 7和Visual Studio 2015.我将我的C#项目设置为x86。

我试图:

  1. Marshal.Copy(...)或Marshal.ReadByte(...)返回以下异常: mscorlib.dll中发生未处理的“System.AccessViolationException”类型异常附加信息:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。

  2. 试图在x86 Windows 7上运行:DLL结果相同(结果不好)。

  3. 尝试将IntPtr更改为byte []我得到了同样的异常,例如Marshal.Copy()

  4. 尝试更改为ref // not help

  5. 示例1已更新:

        [DllImport("DllName.dll")]
        public static unsafe extern int acqStatus(ref ushort* stat, ref uint* err);
    
    
            // Elsewhere in source code in unsafe method
            ushort* stat = 0;
            uint* err = 0;
    
            TCPInterface.acqStatus(ref stat, ref err);
    
            // I have following exception:
            An unhandled exception of type 'System.AccessViolationException' occurred in WindowsFormsApplication1.exe 
            Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
    

1 个答案:

答案 0 :(得分:1)

那是因为ToInt32()ToString()无法按预期工作。这些方法返回指针的内存地址,而不是检索到的值。

对于第一个签名,请将其更改为:

[DllImport("DllName.dll")]
// WORD C++ is equivalent to ushort in C#
public static extern uint acqStatus(ref ushort stat, ref ushort err);

对于第二个,如果没有确切的实现,它会更复杂,但是一个好的尝试将是:

[DllImport("DllName.dll", CharSet = CharSet.Auto)]
public static extern uint getStatus(ref double time, StringBuilder data);