Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C#中设置或获取DLL库的参数? 我有C++库(32位),我想在C语言中加载和使用。DLL正在工作(打开连接、关闭连接和其他没有参数的方法)。问题是,C++参数库的所有方法都有意外的结果。例如:_C#_C++_Variables_Winapi_Dllimport - Fatal编程技术网

如何在C#中设置或获取DLL库的参数? 我有C++库(32位),我想在C语言中加载和使用。DLL正在工作(打开连接、关闭连接和其他没有参数的方法)。问题是,C++参数库的所有方法都有意外的结果。例如:

如何在C#中设置或获取DLL库的参数? 我有C++库(32位),我想在C语言中加载和使用。DLL正在工作(打开连接、关闭连接和其他没有参数的方法)。问题是,C++参数库的所有方法都有意外的结果。例如:,c#,c++,variables,winapi,dllimport,C#,C++,Variables,Winapi,Dllimport,C++库方法规范: unsigned int WINAPI acqStatus (WORD& stat, WORD& err); unsigned int WINAPI getStatus (double& time, TCHAR* data); C#源代码(外部方法): C#第一个方法示例(返回错误值,或将IntPtr转换为整数时出错): 与另一个方法的情况相同,返回TCHAR*。结果是字符串(字节数组)。我不知道如何从数据变量中获取字符串 doubl

C++库方法规范:

unsigned int WINAPI acqStatus (WORD& stat, WORD& err);
unsigned int WINAPI getStatus (double& time, TCHAR* data);
C#源代码(外部方法):

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

与另一个方法的情况相同,返回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

我试图:

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

  • 尝试在x86 Windows 7上运行:DLL结果相同(错误结果)

  • 试图将IntPtr更改为byte[]我得到了与Marshal.Copy()中相同的异常

  • 尝试使用ref/进行更改//没有帮助

  • 示例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.
    

    这是因为
    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);
    

    第一:我完全改变了它,就像你一样,但我有同样的结果。对于ref ushort stat,结果为0x003,正确值必须为0x000和0x004,正确值必须为0x001:-(第二个我正在尝试。在第二个示例中,当我使用Cdecl:CallingConvention.Cdecl时,我遇到了一个异常:托管调试助手“PinvokeStackDistancer”检测到“C:\Users”中存在问题。其他信息:调用PInvoke函数您可以删除
    CallingConvention
    ,然后重试。如果您知道字符集,效果会更好。)您可以直接指定它。我删除了Cdecl,但结果是:mscorlib.dll中发生了类型为“System.AccessViolationException”的未处理异常。其他信息:试图读取或写入受保护的内存。这通常表示其他内存已损坏。这不是Cdecl。停止猜测。您的pinvoke完全错误。您必须在你继续之前,我会更好地理解。@DavidHeffernan THX,对不起,我编辑了第一个示例,但结果与以前一样。请检查它。THX是否有任何想法。它仍然是错误的。它是明显错误的。你有没有努力思考这个问题?只要阅读你写的问题。然后思考。@DavidHeffernan如果它是明显错误的,请帮助mee理解到底什么是不好的,并给mee一个具体的例子来理解它。谢谢。事实上我读错了。对不起。真为我感到羞耻。
    uint
    是正确的。显然这并不重要。当然,你应该检查人们期望的返回值。因此,Arnaud的p/invoke是完美的,考虑到我有。你为什么不用它?
    [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);