这是我的场景:我有一个第三方非托管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