Alexander I.
Alexander I.

Reputation: 2714

C# marshalling for HANDLE and CRITICAL_SECTION

I am developing a C# (.NET Core) application, and I need to call a C function from an external library.

But I am having trouble when marshaling thread_t and lock_t.

This is the C code:

EXPORT void strsvrinit (strsvr_t *svr, int nout);

typedef struct {        /* stream server type */
    int state;          /* server state (0:stop,1:running) */
    ...
    thread_t thread;    /* server thread */
    lock_t lock;        /* lock flag */
} strsvr_t;

#ifdef WIN32
#define thread_t    HANDLE
#define lock_t      CRITICAL_SECTION
#else
#define thread_t    pthread_t
#define lock_t      pthread_mutex_t
#endif

How can I implement marshaling for thread_t (HANDLE) and lock_t (CRITICAL_SECTION)?

Upvotes: 1

Views: 600

Answers (2)

a HANDLE is a *void in C/C++, in C# it is a IntPtr.

CRITICAL_SECTION is a structure:

typedef RTL_CRITICAL_SECTION CRITICAL_SECTION;

typedef struct _RTL_CRITICAL_SECTION {
    PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
    LONG LockCount;
    LONG RecursionCount;
    HANDLE OwningThread; 
    HANDLE LockSemaphore;
    ULONG_PTR SpinCount;
} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;

in C# code:

[StructLayout(LayoutKind.Sequential)]
public struct CRITICAL_SECTION {
    public IntPtr DebugInfo;
    public int LockCount;
    public int RecursionCount;
    public IntPtr OwningThread;
    public IntPtr LockSemaphore;
    public UIntPtr SpinCount;
}

Answered by t3f

Upvotes: 1

David Haim
David Haim

Reputation: 26506

How about just referencing them with IntPtr? I assume you are not going to modify these structures from the C# code, or even try to pass them by value to the C code (bad idea) but to pass their pointer to a P/Invoked function.

So just reference them as IntPtr, which is equivalent to basically void*

Upvotes: 1

Related Questions