2013-08-13 3 views
2

Я пытаюсь использовать C-написанную DLL (API FlyCapture, из Point Gray Research Inc) в коде C#, но всегда получаю ошибку времени выполнения. Здесь у меня есть два примера кода, использующих DLL: один написан на C++, а в другом я попытался сделать то же самое на C#, используя небезопасный контекст.Ошибка в vshost32-clr2.exe при вызове C написана DLL в C#

C++ код:

void Callback(void* Param, int Message, unsigned long lParam) 
{ 
    cout << Message << "\t" << lParam << endl; 
} 

int main(int argc, char *argv[]) 
{ 
    void *context; 
    FlyCaptureCallback *callback = Callback; 

    flycaptureCreateContext(&context); 
    flycaptureModifyCallback(context, callback, NULL, true); 

    _sleep(5000); 

    flycaptureModifyCallback(context, callback, NULL, false); 
    flycaptureDestroyContext(context); 

    return 0; 
} 

C# код:

[DllImport("pgrflycapture.dll")] 
static extern int flycaptureCreateContext(void** pContext); 

[DllImport("pgrflycapture.dll")] 
static extern int flycaptureDestroyContext(void* context); 

[DllImport("pgrflycapture.dll")] 
static extern int flycaptureModifyCallback(void* context, IntPtr pfnCallback, void* pParam, bool bAdd); 

delegate void FlyCaptureCallback(void* Param, int Message, uint lParam); 

static void Callback(void* Param, int Message, uint lParam) 
{ 
    Console.WriteLine(Message.ToString() + "\t" + lParam.ToString()); 
} 

static void Main(string[] args) 
{ 
    void *context; 
    IntPtr callback = Marshal.GetFunctionPointerForDelegate((FlyCaptureCallback) Callback); 

    flycaptureCreateContext(&context); 
    flycaptureModifyCallback(context, callback, null, true); 

    Thread.Sleep(5000); 

    flycaptureModifyCallback(context, callback, null, false); 
    flycaptureDestroyContext(context); 
} 

Цель этой программы заключается в регистрации функции обратного вызова, так что, когда событие происходит в автобусе камеры, эта функция называется , Затем программа ждет 5 секунд и удаляет обратный вызов из регистра. Приложение C++ отлично работает, если я удаляю камеру с компьютера в течение этих 5 секунд, на консоли появляется сообщение. С другой стороны, приложение C# работает только при отсутствии события, поэтому функция обратного вызова не вызывается. Если я попытаюсь удалить камеру с компьютера, функция Callback будет успешно вызвана, и на экране появятся правильные номера, но в Windows появится сообщение о том, что «vshost32-clr2.exe перестала работать» во время функции flycaptureDestroyContext.

Любые идеи? Благодаря!

+0

Какова конкретная ошибка времени выполнения, которую вы получаете? –

+1

Перейдите на страницу образцов FlyCapture и просмотрите образцы. http://www.ptgrey.com/products/pgrflycapture/samples.asp –

+1

Похоже, что Point Gray имеет C# SDK. Есть ли конкретная причина, по которой вы не используете это? Независимо от того, если вы видите странное поведение вокруг обратного вызова из собственного кода, убедитесь, что ваши соглашения о звонках правы: http://blogs.microsoft.co.il/blogs/sasha/archive/2012/01/18/p-invoke -stack-imbalance-mda.aspx – lnmx

ответ

1

У меня есть это! Проблема заключалась в том, что функции API (flycaptureCreateContext, flycaptureModifyCallback и flycaptureDestroyContext) были объявлены в заголовках C как __cdecl, но я не рассматривал их в операторах DllImport. Далее следует скорректированный код C#:

[DllImport("pgrflycapture.dll", CallingConvention = CallingConvention.Cdecl)] 
static extern int flycaptureCreateContext(void** pContext); 

[DllImport("pgrflycapture.dll", CallingConvention = CallingConvention.Cdecl)] 
static extern int flycaptureDestroyContext(void* context); 

[DllImport("pgrflycapture.dll", CallingConvention = CallingConvention.Cdecl)] 
static extern int flycaptureModifyCallback(void* context, FlyCaptureCallback pfnCallback, void* pParam, bool bAdd); 

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] 
delegate void FlyCaptureCallback(void* Param, int Message, uint lParam); 

static void Callback(void* Param, int Message, uint lParam) 
{ 
    Console.WriteLine(Message.ToString() + "\t" + lParam.ToString()); 
} 

static void Main(string[] args) 
{ 
    void *context; 
    FlyCaptureCallback callback = (FlyCaptureCallback) Callback; 

    flycaptureCreateContext(&context); 
    flycaptureModifyCallback(context, callback, null, true); 

    Thread.Sleep(5000); 

    flycaptureModifyCallback(context, callback, null, false); 
    flycaptureDestroyContext(context); 
} 

Thanks lnmx и Jim Mischel за вашу полезную помощь!