這是我的場景:我有一個第三方非託管foo.dll與自動快速回報設備交互,稱之爲FooDevice。我寫了一個關於foo.dll的方法的包裝器,稱它爲FooWrapper,並且用編組和一些錘子敲打我最終使其工作;如您所知,在使用DllImport
時,所有暴露的方法都需要標記爲static
和extern
foo.dll公開了一些方法和回調函數指針;當我嘗試在不同的線程中同時連接兩個設備時,當tryng鉤住此回調函數時,包裝會掛起。 我知道static stuff是線程共享的,所以我想爲每個FooWrapper istances使用不同的AppDomain
。 你認爲這是做這種工作的正確方法嗎?
這一點我FooWrapper的:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void FOO_EventHandlerFunc([In] UInt16 event_id, [In, Out] ref IntPtr data, [In] IntPtr param);
[SuppressUnmanagedCodeSecurity]
internal static class FOO
{
static FOO()
{
//...
}
///
/// FOO_RegisterEventHandler
/// The FOO_RegisterEventHandler function registers an application-defined callback
/// function, which will subsequently be called for all FooDevice generated events.
///
/// long FOO_RegisterEventHandler(FOO_EventHandlerFunc handler, BYTE evmask, LONG param);
///
/// Parameters
/// handler
/// [in] Pointer to an application-defined callback function (see below).
/// evmask
/// [in] Specify which events to enable (see EnableEvents).
/// param
/// [in] An application-defined value to be passed to the callback function
///
/// Return Values
/// If the function succeeds, the return value is zero.
/// If the function fails, the return value is nonzero.
///
/// Remarks
/// The FOO_EventHandlerFunc type defines a pointer to a callback function, which must
/// comply with the following, where FOO_EventHandlerFunc is a placeholder for the
/// application-defined function name.
///
/// void FOO_EventHandlerFunc(WORD event_id, LPVOID data, LONG param);
///
/// Parameters
/// event_id
/// [in] Event index as specified by the FooDevice protocol.
/// data
/// [in] Event data. The type of data depends on event_id.
/// (See the event specifications for FooDevice).
/// param
/// The application-defined value passed during registration.
///
/// Remarks
/// Avoid lengthy callback functions, since it will stall the underlying protocol,
/// thereby interrupting a steady communications flow.
/// FooDevice will only be generating events during operation.
/// That is - between FOO_LogIn and FOO_LogOut.
///
///The handler.
///The evmask.
///The param.
///
[DllImport("foo.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Ansi)]
public static extern UInt32 FOO_RegisterEventHandler([In] [MarshalAs(UnmanagedType.FunctionPtr)] FOO_EventHandlerFunc handler, [In] byte evmask, [In] IntPtr param);
///
/// FOO_LogIn
/// The FOO_LogIn function opens FooDevice for normal operation.
///
/// long FOO_LogIn(LPSTR oper, LPSTR datetime);
///
/// Parameters
/// oper
/// [in] Pointer to a null-terminated string identifying the cashier.
/// The string can have any content, but a maximum of 50 characters will be used.
/// datetime
/// [in] Pointer to a null-terminated string indicating the current date and time.
/// The string must have 'YYYYMMDDhhmmss' format to take effect.
/// Return Values
/// If the function succeeds, the return value is zero.
/// If the function fails, the return value is nonzero.
///
///The oper.
///The datetime.
///
[DllImport("foo.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Ansi)]
public static extern UInt32 FOO_LogIn([In] string oper, [In] string datetime);
//... and so on ...
}
}
您能否提供我的方式來istantiate正確FooWrapper超過一次(在相同或differente線程或應用程序域)?
謝謝你們。 乾杯, Nando
「快速回報裝置」,當你使用它錯誤時,它會衝你臉上嗎?考慮到appdomains會是錯誤的,本機代碼沒有它的概念。使用線程往往是錯誤的,沒有很多代碼可以在多個線程中自由調用,而不會在*客戶端*代碼中進行任何同步。可以肯定的是,死鎖並不是一種不尋常的失敗模式。請聯繫此代碼的供應商或作者以獲取支持。 – 2012-02-03 13:27:38
謝謝漢斯的回覆。不幸的是,移動一個大型跨國公司並不是那麼簡單,考慮到「不要觸摸有效的軟件」的口頭禪。 :-) 但我會嘗試,如果有必要。 再見! :-) – 2012-02-14 16:40:37