1
편집 제공 (당신이 ildjarn 감사를!) : 이C#을 콜백 액세스 위반을
[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 다음 코드를 땅에 제자리에 : C#에서
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;
}
는 내가 가진 :
(일치하고 콜백 함수 서명) 위임을 변경하여 해결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();
}
}
왜'InstallStatusDel'의 첫번째 매개 변수가'string'보다는'StringBuilder'입니까? 'StringBuilder'는 _mutable_ 문자열을위한 것입니다. 어쨌든, 매개 변수에'[MarshalAs (UnmanagedType.LPStr)]'를 추가 할 수 있습니다. – ildjarn
그게 문제 였어! 고맙습니다! –