就个人而言,如果要在其他地方调用 C 代码,我会在那里使用互斥锁。如果这不能让你的船浮起来,你可以很容易地锁定.Net:
static object SomeFunctionLock = new Object();
public static int SomeFunction(int parameter1, int parameter2){
lock ( SomeFunctionLock ){
return _SomeFunction( parameter1, parameter2 );
}
}
[DllImport("MyDll", CallingConvention = CallingConvention.Cdecl)]
internal static extern int _SomeFunction(int parameter1, int parameter2);
[编辑..]
正如所指出的,这会序列化对在这种情况下您无法自己执行的功能的访问。您有一些 C/C++ 代码(错误地 IMO)在调用公开函数期间使用全局状态。
正如您所观察到的那样,该__declspec(thread)
技巧在这里不起作用,那么我将尝试将您的状态/上下文作为不透明的指针来回传递,如下所示:-
extern "C"
{
int _SomeOtherFunction( void* pctx, int p1, int p2 )
{
return stuff;
}
// publically exposed library function
int __declspec(dllexport) SomeFunction(int parameter1, int parameter2)
{
StateContext ctx;
return _SomeOtherFunction( &ctx, parameter1, parameter2 );
}
// another publically exposed library function that takes state
int __declspec(dllexport) SomeFunctionWithState(StateContext * ctx, int parameter1, int parameter2)
{
return _SomeOtherFunction( ctx, parameter1, parameter2 );
}
// if you wanted to create/preserve/use the state directly
StateContext * __declspec(dllexport) GetState(void) {
ctx = (StateContext*) calloc( 1 , sizeof(StateContext) );
return ctx;
}
// tidy up
void __declspec(dllexport) FreeState(StateContext * ctx) {
free (ctx);
}
}
和之前对应的 C# 包装器:
[DllImport("MyDll", CallingConvention = CallingConvention.Cdecl)]
internal static extern int SomeFunction(int parameter1, int parameter2);
[DllImport("MyDll", CallingConvention = CallingConvention.Cdecl)]
internal static extern int SomeFunctionWithState(IntPtr ctx, int parameter1, int parameter2);
[DllImport("MyDll", CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr GetState();
[DllImport("MyDll", CallingConvention = CallingConvention.Cdecl)]
internal static extern void FreeState(IntPtr);