gpt4 book ai didi

C# 和 C++,从 C# 调用 C++ dll 时出现运行时错误

转载 作者:太空狗 更新时间:2023-10-29 21:08:25 24 4
gpt4 key购买 nike

我已经编写了一个 C++ 包装器 DLL 供 C# 调用。 DLL 已经过测试,并且可以与我的 C++ 测试程序一起正常工作。

现在与 C# 集成,我遇到运行时错误并崩溃。无法使用调试器查看更多详细信息。

C++端只有一种方法:

#ifdef DLLWRAPPERWIN32_EXPORTS
#define DLLWRAPPERWIN32_API __declspec(dllexport)
#else
#define DLLWRAPPERWIN32_API __declspec(dllimport)
#endif

#include "NB_DPSM.h"

extern "C" {
DLLWRAPPERWIN32_API int WriteGenbenchDataWrapper(string fileNameToAnalyze,
string parameterFileName,
string baseNameToSaveData,
string logFileName,
string& message) ;
}

在C#端,有一个定义,

[DllImport("..\\..\\thirdParty\\cogs\\DLLWrapperWin32.dll")]
public static extern int WriteGenbenchDataWrapper(string fileNameToAnalyze,
string parameterFileName,
string baseNameToSaveData,
string logFileName,
ref string message);

和一个电话:

 string msg = "";
int returnVal = WriteGenbenchDataWrapper(rawDataFileName,
parameterFileName, outputBaseName, logFileName, ref msg);

我猜函数的最后一个参数一定有问题。 C++中的string&应该是C#中的ref string

EDIT:

我们真的需要extern "C"吗?

EDIT 2:

在我从 dll 中删除 extern "C 后,我得到了 EntryPointNotFoundException。当我使用 DLL Export Viewer 查看 dll 时,我发现函数名称是 "int __cdecl WriteGenbenchDataWrapper(class std::...”我需要包含“__cdecl”吗?

最佳答案

使用 PInvoke 进行编码有很多规则。供引用Marsheling between managaed & unmanaged

首先关注 C# 方面。如果您预先知道消息的合理大小,则可以使用 StringBuilder 类型并定义该大小,例如。

[DllImport("DLLWrapperWin32.dll")]
public static extern int WriteGenbenchDataWrapper(string fileNameToAnalyze,
string parameterFileName,
string baseNameToSaveData,
string logFileName,
StringBuilder message
int messageLength );

名称消息(和其他帖子)的印象表明您不知道前面的大小,并且您不会将部分消息传递给函数,所以可能

[DllImport("DLLWrapperWin32.dll")]
public static extern int WriteGenbenchDataWrapper(in string fileNameToAnalyze,
in string parameterFileName,
in string baseNameToSaveData,
in string logFileName,
out string message );

现在在 C/C++ 端 - 匹配第二个定义

extern "C" // if this is a C++ file to turn off name mangling for this function only
int WriteGenbenchDataWrapper( char * fileNameToAnalyze,
char * parameterFileName,
char * baseNameToSaveData,
char * logFileName,
char ** message ) {
string internalMessage;
SomeFunc( internalMessage ); // these functions won't have extern "C" applied
* message = (char *)::CoTaskMemAlloc(internalMessage.length()+1);
strcpy(* message, internalMessage.c_str());
}

考虑unicode/ansi字符串也很重要,引用[MarshalAsAttribute(UnmanagedType.LPWSTR)]

对于 Release模式,您需要删除开发路径设置“..\..\thirdParty\cogs”

关于C# 和 C++,从 C# 调用 C++ dll 时出现运行时错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3064062/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com