2013-03-07 1 views
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(); 
    } 
} 
+0

왜'InstallStatusDel'의 첫번째 매개 변수가'string'보다는'StringBuilder'입니까? 'StringBuilder'는 _mutable_ 문자열을위한 것입니다. 어쨌든, 매개 변수에'[MarshalAs (UnmanagedType.LPStr)]'를 추가 할 수 있습니다. – ildjarn

+0

그게 문제 였어! 고맙습니다! –

답변

2

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

에 ildjarn 감사합니다!

관련 문제