C/C++ DLL 在 .NET Framework 从 3.5 升级到 4.6 后失败
C/C++ DLL failing after .NET framework upgrade from 3.5 to 4.6
我有一个名为 Agent 的应用程序,它有 2 个项目:
- C# 项目
- C/C++ DLL
整个应用程序 运行 使用我们用 vs2008 构建的 .NET 3.5 没问题。
由于某些要求,我们将 .Net Framework 升级到 4.6 和 vs 2019 来构建它。
现在我的应用程序服务运行但看起来 C/C++ dll 导出在某处失败。
我试过的:
C#端
TAgtLib.TAStartAgent(mServerPort, mName, mBinDir, mPath, mDebug,
mStdout, mDefaultLogDays, mEncryptOnly);
其中 TAgtLib 是包装器 class,它像这样声明这些 C/C++ 函数
[DllImport("ccplusplus.dll", CharSet = CharSet.Ansi)]
public static extern int TAStartAgent(int port, string name, string bindir, string rundir, string debugOption, string stdoutOption, int mDefaultLogDays, int encryptonly);
C++ 定义:
extern "C" int _stdcall TAStartAgent(int PortNum, char *Name, char *binDir, char *runDir, char *debugOption, char *stdoutOption, int mDefaultLogDays, int encryptonly);
每当从 c# 中调试此函数时,它就会进入内存冲突。
当我们更改为 binDir.ToArray() 并将 dllexport 声明更改为 char[] binDir 时,类似于 runDir,它没有出现访问冲突,但它进入了 dll 内部。
尽管 C dll 仍然存在问题。
谁能指导我从 3.5 迁移到 4.6 后必须影响 c/c++ dll 的是什么?
我是 C# 新手。
谢谢
这很可能发生,因为 .Net 4 改变了纠正不正确 P/Invoke 调用约定的方式。
来自https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/ee941656(v=vs.100):
To improve performance in interoperability with unmanaged code,
incorrect calling conventions in a platform invoke now cause the
application to fail. In previous versions, the marshaling layer
resolved these errors up the stack.
要解决此问题,您必须在 P/Invoke 声明中指定正确的调用约定,例如
DllImport("ccplusplus.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int TAStartAgent(int port, string name, string bindir, string rundir, string debugOption, string stdoutOption, int mDefaultLogDays, int encryptonly);
尽管您当然需要为您的 DLL 指定正确的调用约定。
我有一个名为 Agent 的应用程序,它有 2 个项目:
- C# 项目
- C/C++ DLL
整个应用程序 运行 使用我们用 vs2008 构建的 .NET 3.5 没问题。 由于某些要求,我们将 .Net Framework 升级到 4.6 和 vs 2019 来构建它。 现在我的应用程序服务运行但看起来 C/C++ dll 导出在某处失败。 我试过的: C#端
TAgtLib.TAStartAgent(mServerPort, mName, mBinDir, mPath, mDebug,
mStdout, mDefaultLogDays, mEncryptOnly);
其中 TAgtLib 是包装器 class,它像这样声明这些 C/C++ 函数
[DllImport("ccplusplus.dll", CharSet = CharSet.Ansi)]
public static extern int TAStartAgent(int port, string name, string bindir, string rundir, string debugOption, string stdoutOption, int mDefaultLogDays, int encryptonly);
C++ 定义:
extern "C" int _stdcall TAStartAgent(int PortNum, char *Name, char *binDir, char *runDir, char *debugOption, char *stdoutOption, int mDefaultLogDays, int encryptonly);
每当从 c# 中调试此函数时,它就会进入内存冲突。
当我们更改为 binDir.ToArray() 并将 dllexport 声明更改为 char[] binDir 时,类似于 runDir,它没有出现访问冲突,但它进入了 dll 内部。
尽管 C dll 仍然存在问题。
谁能指导我从 3.5 迁移到 4.6 后必须影响 c/c++ dll 的是什么?
我是 C# 新手。
谢谢
这很可能发生,因为 .Net 4 改变了纠正不正确 P/Invoke 调用约定的方式。
来自https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/ee941656(v=vs.100):
To improve performance in interoperability with unmanaged code, incorrect calling conventions in a platform invoke now cause the application to fail. In previous versions, the marshaling layer resolved these errors up the stack.
要解决此问题,您必须在 P/Invoke 声明中指定正确的调用约定,例如
DllImport("ccplusplus.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int TAStartAgent(int port, string name, string bindir, string rundir, string debugOption, string stdoutOption, int mDefaultLogDays, int encryptonly);
尽管您当然需要为您的 DLL 指定正确的调用约定。