【问题标题】:Import a C++ DLL into C#将 C++ DLL 导入 C#
【发布时间】:2021-01-21 01:42:14
【问题描述】:

我尝试在我的 C# 项目中实现一个 C++ DLL。我给出了以下头文件:

#ifdef EBEXPORT
const long EBDECL
#else
const long EBDECL __declspec(dllimport)
#endif

const long EBCALL __stdcall


#if defined (__cplusplus)
extern "C" 
{
#endif

EBDECL long EBCALL EbInitTcp(long nUnit, const char* pIP, long nIPSize);

#if defined (__cplusplus)
}
#endif

这是我用来在 C# 中实现 DLL 的代码:

using System.Runtime.InteropServices;

namespace NoName
{
    class DLLImport
    {
        [DllImport("C:/lib/host.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern long EbInitTcp(long nUnit, string pIP, long nIPSize);

        public void Init()
        {
            string ip = "192.168.0.1";
            EbInitTcp(1, ip, ip.Length));
        }

    }
}

如果我执行代码,我会得到 PInvokeStackImbalance 异常。 你能帮帮我吗?

【问题讨论】:

  • int EbInitTcp(int nUnit, string pIP, int nIPSize).
  • 调用约定通常用#define定义,即#define EBCALL __stdcall

标签: c# c++ dll dllimport


【解决方案1】:

验证您的调用约定;请注意 extern "C" 默认为 CallingConvention.Cdecl。此错误通常是由错误的调用约定引起的。

还要注意 C# 的 long 和 C++ 的 long 可能不同。

您似乎正在尝试指定__stdcall,但这是语法错误。在任何情况下,请确保您的调用约定是同步的。

【讨论】:

  • c++头文件给定了,不能改。
  • 您的代码甚至无法编译;请积极验证调用约定是你认为的那样。
  • 我可以无错误地编译代码;我还验证了调用约定。
  • "extern "C" 默认为 CallingConvention.Cdecl" 没那么多。 extern "C" 没有区别,所有全局函数都将默认调用约定 specified on the compiler command-line
【解决方案2】:

不平衡的原因可能是调用约定不匹配(cdeclstdcall)或函数参数在大小和类型方面不匹配。

C++ 调用约定定义有点不寻常,它通常使用#define 定义。

#ifdef EBEXPORT
  #define EBDECL __declspec(dllexport)
#else
  #define EBDECL __declspec(dllimport)
#endif

#define EBCALL __stdcall

#if defined (__cplusplus)
extern "C" 
{
#endif

EBDECL const long EBCALL EbInitTcp(long nUnit, const char* pIP, long nIPSize);

#if defined (__cplusplus)
}
#endif

在 C# 方面;

using System.Runtime.InteropServices;

namespace NoName
{
    class DLLImport
    {
        [DllImport("C:/lib/host.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern long EbInitTcp(int nUnit, string pIP, int nIPSize);

        public void Init()
        {
            string ip = "192.168.0.1";
            EbInitTcp(1, ip, ip.Length));
        }

    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-06
    • 1970-01-01
    • 2021-04-12
    • 1970-01-01
    • 1970-01-01
    • 2016-01-22
    • 2010-10-04
    • 1970-01-01
    相关资源
    最近更新 更多