【问题标题】:Mixing managed and unmanaged code issue混合托管和非托管代码问题
【发布时间】:2014-02-07 11:36:34
【问题描述】:

我有以下代码

    System::Void MainForm::initLoadCell(){
        //Open the first found LabJack U3 over USB.
        lngErrorcode = OpenLabJack (LJ_dtU3, LJ_ctUSB, "1", TRUE, &lngHandle);

        //Load defualt config
        lngErrorcode = ePut (lngHandle, LJ_ioPIN_CONFIGURATION_RESET, 0, 0, 0);

        //Setup FIO0 as an analogue input port
        lngErrorcode = ePut (lngHandle, LJ_ioPUT_ANALOG_ENABLE_BIT,0,1,0);

        //Obtain error string
        char* errorcode = new char;
        ErrorToString(lngErrorcode, errorcode);

        // Convert the c string to a managed String.
        String ^ errorString = Marshal::PtrToStringAnsi((IntPtr) (char *) errorcode);

        MainForm::textBox_LoadCellError->Text = errorString;

        Marshal::FreeHGlobal((IntPtr)errorcode);
}

这在我直接从 Visual Studio 运行程序时有效,但是当我构建 .exe 文件并作为独立运行时,我收到以下错误

Problem signature:
Problem Event Name: APPCRASH
Application Name:   BenchTester.exe
Application Version:    0.0.0.0
Application Timestamp:  52f4c0dd
Fault Module Name:  ntdll.dll
Fault Module Version:   6.1.7601.18247
Fault Module Timestamp: 521ea8e7
Exception Code: c0000005
Exception Offset:   0002e3be
OS Version: 6.1.7601.2.1.0.256.1
Locale ID:  3081
Additional Information 1:   0a9e
Additional Information 2:   0a9e372d3b4ad19135b953a78882e789
Additional Information 3:   0a9e
Additional Information 4:   0a9e372d3b4ad19135b953a78882e789

Read our privacy statement online:
http://go.microsoft.com/fwlink/?linkid=104288&clcid=0x0409

If the online privacy statement is not available, please read our privacy                      statement       offline:
C:\Windows\system32\en-US\erofflps.txt

我知道是下面这行引起的

ErrorToString(lngErrorcode, errorcode);

这是对第 3 方代码的调用,我认为错误与未正确处理非托管代码的代码有关,但我不确定在哪里。有人可以指出我正确的方向。

【问题讨论】:

    标签: .net c++-cli unmanaged managed


    【解决方案1】:

    我不知道 ErrorToString 期望的参数是什么,但我会说它是一个 char*,表示指向可以存储结果字符串的缓冲区的指针。

    在这种情况下,您的代码:

    //Obtain error string
    char* errorcode = new char;
    ErrorToString(lngErrorcode, errorcode);
    

    看起来不对(它正在分配一个字符)。

    尝试将其更改为:

    //Obtain error string
    char* errorcode = new char[1024];
    ErrorToString(lngErrorcode, errorcode);
    

    看看这是否有效(在这种情况下不要忘记你需要稍后释放内存)。

    希望这会有所帮助。

    【讨论】:

    • 谢谢这实际上会有所帮助,但没有解决问题,我认为只需使用新字符就可以创建所需的大小。无论如何,不​​幸的是我仍然有错误。我找到了一个解决方法,因为第 3 方硬件实际上带有一个 .net 包装器,所以现在一切都很好,谢谢。
    • 更好的是:char errorCode[1024]; 在不需要时避免动态分配。
    【解决方案2】:

    你把这一切弄得太复杂了。而不是

        //Obtain error string
        char* errorcode = new char;
        ErrorToString(lngErrorcode, errorcode);
    
        // Convert the c string to a managed String.
        String ^ errorString = Marshal::PtrToStringAnsi((IntPtr) (char *) errorcode);
    
        MainForm::textBox_LoadCellError->Text = errorString;
    
        Marshal::FreeHGlobal((IntPtr)errorcode);
    

    你只需要:

        //Obtain error string
        char errorString[1024];
        ErrorToString(lngErrorcode, errorString);
        MainForm::textBox_LoadCellError->Text = gcnew System::String(errorString);
    

    您最初有两个问题:没有足够大的缓冲区,以及分配和释放功能不匹配。使用new 后,您必须使用delete,而不是Marshal::FreeHGlobal。但是根本没有理由进行任何动态分配。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-24
      相关资源
      最近更新 更多