none
c#下调用dll出错 RRS feed

  • 问题

  • 函数原型:

    extern "C" _declspec(dllexport)int  ReadShpPath(LPCSTR path)

    C#      

     [DllImport(@"c:\ShpMachName.dll", CharSet = CharSet.Ansi)]

            public static extern int ReadShpPath(string path);

    异常:

    对 PInvoke 函数“ShpMachName_csharpCall!ShpMachName_csharpCall.Form1::ReadShpPath”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。

     

    2010年10月25日 7:41

答案

  • 试试看指定 CallingConvention 为 CDecl 或者修改 C++ 代码加上 WINAPI。例如:

    extern "C" {
        DLLEXPORT INT WINAPI MyFunc(LPCTSTR myParam);
    }


    Mark Zhou
    • 已标记为答案 zhzhzh 2010年10月25日 9:00
    2010年10月25日 8:55

全部回复

  • 3.5下没问题,4.0就会出错!

    这是为什么?请教各位

    2010年10月25日 7:48
  • 试试看指定 CallingConvention 为 CDecl 或者修改 C++ 代码加上 WINAPI。例如:

    extern "C" {
        DLLEXPORT INT WINAPI MyFunc(LPCTSTR myParam);
    }


    Mark Zhou
    • 已标记为答案 zhzhzh 2010年10月25日 9:00
    2010年10月25日 8:55
  • 试试看指定 CallingConvention 为 CDecl 或者修改 C++ 代码加上 WINAPI。例如:

    extern "C" {
        DLLEXPORT INT WINAPI MyFunc(LPCTSTR myParam);
    }


    Mark Zhou

    太感谢你了!可以正确调用了

    能给我说下为什么这样就可以正常运行吗?

    2010年10月25日 9:00
  • 这是有关 Calling Convention 的问题。因为 Windows 应用程序可能会是由很多种不同标准的语言而编译而成的,因此,要在不同的程序之间的 API 通信,就可能需要一个标准的调用约定。比如,Pascal 和 C++ 写的程序,其方法参数的传递顺序会不同;或者说托管代码和非托管代码它们对于 String 类型的处理就完全不同。CDecl 表示其函数符合 C/C++ 语言规范;而 WINAPI 宏定义在 Windows 系统上可以通用的一种 API 调用约定 (现在是 stdcall)。

    我自己不是搞 C++ 的,这里有其他版主是 C++ MVP,可以找他们问问更具体的信息。


    Mark Zhou
    2010年10月25日 9:28
  • VC项目向导创建的默认工程的参数入栈约定是cdecl而.Net和Windows API的是stdcall (#define WINAPI __stdcall)。这两个调用约定的入栈参数清除方法不同。如果DLL客户端需要被多种语言调用的话,建议在导出的函数之前加__stdcall以方便其他语言使用。



    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    2010年10月25日 12:23
    版主