gpt4 book ai didi

来自 C++ 的 C# 回调提供访问冲突

转载 作者:行者123 更新时间:2023-11-30 04:20:27 34 4
gpt4 key购买 nike

编辑(谢谢 ildjarn!):通过将委托(delegate)(和回调函数签名匹配)更改为

来解决
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void InstallStatusDel([MarshalAs(UnmanagedType.LPStr)]string Mesg, int Status);

原帖:

我遇到一个用 C# 编写的 .net 应用程序调用 C dll 中的函数的问题。我看过其他有类似问题的线程,但我一定遗漏了一些不同的东西。当我在 C# 中对此进行调试时,我能够在 InstallStatusCallback 中命中断点,但是当执行退出 InstallStatusCallback 时,会出现 AccessViolationException。我已经尝试使用 C 进行调试,并且在执行从回调返回之前发生访问冲突。感谢您的任何输入。

C dll 中的项目设置默认设置为使用 __cdecl。在 C DLL 中,以下代码就位:

typedef void (__cdecl *StatusCallback)(const char* Mesg, int Status);
__declspec(dllexport) int Install(void* thing1, void* thing2, void* thing3, StatusCallback Func);


int Install(void* thing1, void* thing2, void* thing3, StatusCallback Func)
{
Func("msg", 3);
return 0;
}

在 C# 中我有:

public partial class InstallerStatus : Form
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void InstallStatusDel(StringBuilder Mesg, int Status);

public static extern int Install(IntPtr thing1, IntPtr thing2, IntPtr thing3, InstallStatusDel Func);
[DllImport("myDll.dll", CallingConvention = CallingConvention.Cdecl)]

private IntPtr mThing1;
private IntPtr mThing2;
private InstallStatusDel mInstallStatusFunc;
private BackgroundWorker mInstallWorker;

public InstallerStatus(IntPtr pThing1, IntPtr pThing2)
{
InitializeComponent();

mThing1 = pThing1;
mThing2 = pThing2;
mInstallStatusFunc = InstallStatusCallback;

mProgressBar.Minimum = 0;
mProgressBar.Maximum = 100;
mProgressBar.Value = 0;

mInstallWorker = new BackgroundWorker();
mInstallWorker.DoWork += new DoWorkEventHandler(InstallWork);
mInstallWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(InstallWork_Completed);
}

private void InstallWork(object sender, DoWorkEventArgs e)
{
Install(mThing1, mThing2, IntPtr.Zero, mInstallStatusFunc);
}

private void InstallWork_Completed(object sender, RunWorkerCompletedEventArgs e)
{
Close();
}

private void InstallStatusCallback(StringBuilder PartName, int Status)
{
}

private void InstallLoad_Shown(object sender, EventArgs e)
{
mInstallWorker.RunWorkerAsync();
}
}

最佳答案

通过将委托(delegate)(和回调函数签名匹配)更改为

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void InstallStatusDel([MarshalAs(UnmanagedType.LPStr)]string Mesg, int Status);

谢谢 ildjarn!

关于来自 C++ 的 C# 回调提供访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15280721/

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