gpt4 book ai didi

c# - 从 C# 应用程序将结构列表传递给 C++ DLL

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:47:07 26 4
gpt4 key购买 nike

我正在尝试将结构作为参数从 C# 应用程序传递到 C++ MFC DLL。 DLL 在结构对象中填充记录并返回给 C# 应用程序。所以在这里我在 C# 应用程序中使用“out”关键字来调用 C++ 方法。当我执行它时,它失败并出现错误“试图读取或写入 protected 内存。这通常表明其他内存已损坏。”我在 C++ DLL 中分配内存来存储记录并将其分配给 out 参数。我可以在结构对象中发送数据并在 C++ DLL 中打印它,但无法在 DLL 端对结构对象进行修改并返回到 C# 应用程序。

有人可以帮忙吗

NativeDLLHelper.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);
}

主.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++ 动态链接库:

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 可靠地做到这一点。只能调用static C++ 成员函数。请注意,此函数根本不需要是实例方法,它实际上并不使用类的实例成员。

这不是唯一的问题,还有一个令人讨厌的内存管理问题。该函数使用::operator new 分配内存,内存需要由调用者释放。但是 C# 程序不能这样做,它无权访问 C++ 代码使用的::operator delete。由于这个原因,这种函数很难从 C++ 程序中可靠地使用,当你从 C# 中使用它时,它并没有变得更好。正确的做法是让调用者传递数组。换句话说,APPDATA[] 和一个额外的参数,说明传递的数组有多长。

如果您不能重写此函数,那么您必须使用 C++/CLI 语言为此类编写一个包装器。非常重要的是,此包装器使用与 C++ DLL 完全相同的编译器和 CRT 版本。

关于c# - 从 C# 应用程序将结构列表传递给 C++ DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20611820/

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