将结构的列表从C#应用程序传递到C++DLL
Passing list of struct to C++ DLL from C# Application
我正试图将struct作为参数从C#应用程序传递到C++MFC DLL。DLL填充结构对象中的记录并返回到C#应用程序。所以我在C#应用程序中使用了"out"关键字来调用C++方法。当我执行它时,它失败了,错误为"尝试读取或写入受保护的内存。这通常表明其他内存已损坏。"我正在C++DLL中分配内存来存储记录并将其分配给out参数。我可以在结构对象中发送数据并在C++DLL中打印,但无法在DLL端的结构对象中进行修改并返回到C#应用程序。
有人能帮忙吗。
NativeDLL Helper.cs
class NativeDLLHelper
{
const int FIELD_LENGTH = 255;
[StructLayout(LayoutKind.Sequential)]
public struct APPDATA
{
public int ID;
public int Version;
[MarshalAs(UnmanagedType.LPTStr, SizeConst = FIELD_LENGTH)]
public string AppName;
};
[DllImport("Parser.dll", EntryPoint = "?FillLstStructData@DLLWrapper@@QAEXAAPAU_APPDATA@1@@Z")]
public static extern void FillLstStructData(out APPDATA[] AppDataStruct);
}
Main.cs
NativeDLLHelper.APPDATA[] lstFillAppDataStruct;
NativeDLLHelper.FillLstStructData(out lstFillAppDataStruct);
for (int i = 0; i < lstFillAppDataStruct.Length; i++)
{
Console.WriteLine(" ID[{0:G}]:{1:G}", i, lstFillAppDataStruct[i].ID);
Console.WriteLine(" Version[{0:G}]:{1:G}", i, lstFillAppDataStruct[i].Version);
Console.WriteLine(" AppName[{0:G}]:{1:G}", i, lstFillAppDataStruct[i].AppName);
}
C++DLL:
static const int FIELD_LENGTH = 128;
typedef struct _APPDATA
{
int ID;
double Version;
TCHAR AppName[FIELD_LENGTH];
}APPDATA;
extern "C" __declspec(dllexport) FillLstStructData(APPDATA* &pAppData)
{
APPDATA *localAppDataStruct = new APPDATA[2];
localAppDataStruct[0].ID = 1;
localAppDataStruct[0].Version = 1.1;
_tcscpy(localAppDataStruct[0].AppName, L"MS Visual Studio 2010");
localAppDataStruct[1].ID = 2;
localAppDataStruct[1].Version = 2.1;
_tcscpy(localAppDataStruct[1].AppName, L"MS Office 2010");
pAppData = localAppDataStruct;
}
您导出的函数取消映射到:
void __thiscall DLLWrapper::FillLstStructData(struct DLLWrapper::_APPDATA * &)
这使它成为C++类的实例方法。你不能pinvoke这样的方法,它们需要首先创建C++对象,而你不能用pinvoke可靠地做到这一点。只有静态C++成员函数才能被pinvoked。请注意,这个函数根本不需要是实例方法,它实际上并不使用类的实例成员。
这不是唯一的问题,还有一个令人讨厌的内存管理问题。函数使用::operator new分配内存,内存需要由调用方释放。但C#程序无法做到这一点,它无法访问C++代码使用的::运算符delete。这种函数很难从C++程序中可靠地使用,因此,当你从C#中使用它时,它不会变得更好。正确的方法是允许调用者传递数组。换句话说,APPDATA[]和一个额外的参数,说明传递的数组有多长。
如果不能重写此函数,则必须使用C++/CLI语言为此类编写包装器。非常重要的是,这个包装器使用与C++DLL完全相同的编译器和CRT版本。
相关文章:
- 为什么导入Mixed native/CLR lib.dll的本机C++应用程序没有在Mixed lib.dll中的外部变
- 如何在 64 位 vb.net Windows 应用程序中引用 32 位 dll
- C# DLL 从C++应用程序调用 SOAP Web 服务
- 将 c++ 生成器应用程序与外部 dll 结合使用
- WinDeployqt 不会为调试应用程序部署 Qwindowsd.dll
- Log4net,将日志消息从 c++ dll 发送到 c# 应用程序?
- 调试 ASP MVC 应用程序中使用的C++ DLL
- Qt应用程序找不到第三方DLL并崩溃
- 如何将从控制台应用程序C++回调设置为C++ COM DLL
- 我可以用C++/WinRT编写一个DLL,供windows桌面应用程序(而不是UWP)或Unity插件使用吗
- .NET核心应用程序无法加载C++DLL
- 在通用 Windows 应用程序C++上使用 win32 DLL 库
- 从 C# Windows 应用程序调用 C dll 会导致 svchost.exe 崩溃
- 使用 C++ dll 运行 c# 应用程序会生成无法加载异常
- 为什么我的 C# 应用程序无法加载我的 C++ dll?
- 应用程序仅在qt调试器中加载dll,而不是独立加载
- 如果在 DLL 和调用应用程序中使用 GPGPU API,会发生什么情况
- C++ XE 5 应用程序和C++生成器 5 dll 兼容性
- Cygwin1.dll c++ 应用程序错误
- 在线更新DLL应用程序