Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# calling c dll functions whose return type is struct* (I don't have the struct c code/definition)

I have a library called MT7Trace.dll and its header MT7Trace.h. I would like to be able to use the functions included in this dll in c# code but I am not capable of importing them properly. Taking as an example these two functions:

MT7TRACE MT7TraceEnum MT7TraceCreateEnum (void);
MT7TRACE MT7TraceSensor MT7TraceGetNextSensor (MT7TraceEnum hEnumerator);

where:

typedef struct tagMT7TraceEnum * MT7TraceEnum;

My naive attempt so far has been as follows:

[DllImport("MT7Trace.dll")]
public static extern IntPtr MT7TraceCreateEnum(); //MT7TRACE MT7TraceEnum T7TraceCreateEnum (void);

[DllImport("MT7Trace.dll")]
public static extern IntPtr MT7TraceGetNextSensor (IntPtr hEnumerator);//MT7TRACE MT7TraceSensor MT7TraceGetNextSensor (MT7TraceEnum hEnumerator);

But when testing this imported functions:

private bool InitializeOneSensor()
{
    var hEnum = MT7TraceCreateEnum();

    var sensorCtr  = 0;
    MT7TraceSensor hSensor;
    while ((hSensor = MT7TraceGetNextSensor(hEnum)) != IntPtr.Zero)
    {
        // Do something else ..
        DllTraceReleaseSensor(hSensor);
        sensorCtr++;
    }
    DllTraceReleaseEnum(hEnum);
    return sensorCtr ==1;
}

where

using MT7TraceEnum    = System.IntPtr;
using MT7TraceSensor  = System.IntPtr;

I have have an exception:

A call to PInvoke function 'Atracsys.Framework!Atracsys.MicroTouchDevice::MT7TraceGetNextSensor' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

I have seen some examples that explain how to create/recreate a struct to call a dll function with it but, in those the c struct definition was available somewhere:

struct XXX{
   type1 fiel1;
   type1 fiel1;
   ...

};

Thus, to call the dll function an equivalent c sharp structure was created and used to call it.

In my case I do not have the struct definition (as you can see looking at MT7Trace.h below)

Any suggestions?

This is the content of the MT7Trace.h code:

/*******************************************************************************
Copyright 2009 3M. All rights reserved.

Program Name:  MT7Trace
Module Name:   MT7Trace.h

Summary: Application interface for MT 7 Software Trace library

Description:
   This header file defines the application interface for the MT 7 Software
   Trace library. This interface allows an application to enumerate touch
   sensors and obtain traces from the sensors.

Notes:

*******************************************************************************/

#ifndef __MT7TRACE_H__
#define __MT7TRACE_H__

#ifdef __cplusplus
extern "C"
{
#endif

/******************************************************************************/
/* I N C L U D E   F I L E S                                                  */

/* Global Includes */

/* Project Includes */

/* Local Includes */

/******************************************************************************/
/* C O N S T A N T S                                                          */

#ifndef MT7TRACE
#if defined (WIN32) || defined (UNDER_CE)
#define MT7TRACE __declspec (dllimport)
#else
#define MT7TRACE
#endif
#endif


/******************************************************************************/
/* G L O B A L   D A T A   T Y P E S                                          */

typedef enum
{
   MT7TraceReason_Arrival = 1,
   MT7TraceReason_Departure = 2,
   MT7TraceReason_NewTrace = 3,
   MT7TraceReason_NewEvent = 4,
} MT7TraceReason;
typedef void (* MT7TraceCallback) (MT7TraceReason eReason, void * hItem,
                                   void * pvUserCode);
typedef enum
{
   MT7TraceEvent_Touchdown = 0,
   MT7TraceEvent_Drag = 1,
   MT7TraceEvent_Liftoff = 2,
} MT7TraceEventType;
typedef struct tagMT7TraceEnum * MT7TraceEnum;
typedef struct tagMT7TraceSensor * MT7TraceSensor;
typedef struct tagMT7TraceTrace * MT7TraceTrace;
typedef struct tagMT7TraceEvent * MT7TraceEvent;

/******************************************************************************/
/* P U B L I C   D A T A                                                      */


/******************************************************************************/
/* G L O B A L   D A T A                                                      */


/******************************************************************************/
/* G L O B A L   F U N C T I O N   P R O T O T Y P E S                        */


// Enumeration API
MT7TRACE MT7TraceEnum   MT7TraceCreateEnum      (void);
MT7TRACE unsigned int   MT7TraceGetEnumID       (MT7TraceEnum hEnumerator);
MT7TRACE MT7TraceEnum   MT7TraceCloneEnum       (MT7TraceEnum hEnumerator);
MT7TRACE MT7TraceSensor MT7TraceGetNextSensor   (MT7TraceEnum hEnumerator);
MT7TRACE void           MT7TraceReleaseEnum     (MT7TraceEnum hEnumerator);

// Sensor API
MT7TRACE unsigned int   MT7TraceGetSensorID         (MT7TraceSensor hSensor);
MT7TRACE const char *   MT7TraceGetSensorName       (MT7TraceSensor hSensor);
MT7TRACE MT7TraceSensor MT7TraceCloneSensor         (MT7TraceSensor hSensor);
MT7TRACE MT7TraceTrace  MT7TraceGetNextTrace        (MT7TraceSensor hSensor);
MT7TRACE void           MT7TraceSetSensorCallback   (MT7TraceSensor hSensor,MT7TraceCallback fnCallback,void * pvUserCode);
MT7TRACE void           MT7TraceReleaseSensor       (MT7TraceSensor hSensor);

// Trace API
MT7TRACE unsigned int   MT7TraceGetTraceID          (MT7TraceTrace hTrace);
MT7TRACE MT7TraceTrace  MT7TraceCloneTrace          (MT7TraceTrace hTrace);
MT7TRACE MT7TraceEvent  MT7TraceGetNextEvent        (MT7TraceTrace hTrace);
MT7TRACE MT7TraceEvent  MT7TraceGetPriorEvent       (MT7TraceTrace hTrace,unsigned int nOffset);
MT7TRACE void           MT7TraceSetNextEvent        (MT7TraceTrace hTrace,unsigned int nIndex);
MT7TRACE unsigned int   MT7TraceGetEventCount       (MT7TraceTrace hTrace);
MT7TRACE MT7TraceEvent  MT7TraceGetEvent            (MT7TraceTrace hTrace,unsigned int nIndex);
MT7TRACE MT7TraceSensor MT7TraceGetTraceSensor      (MT7TraceTrace hTrace);
MT7TRACE void           MT7TraceSetTraceCallback    (MT7TraceTrace hTrace,MT7TraceCallback fnCallback,void * pvUserCode);
MT7TRACE void           MT7TraceReleaseTrace        (MT7TraceTrace hTrace);

// Event API
MT7TRACE unsigned int       MT7TraceGetEventID      (MT7TraceEvent hEvent);
MT7TRACE MT7TraceEvent      MT7TraceCloneEvent      (MT7TraceEvent hEvent);
MT7TRACE MT7TraceEventType  MT7TraceGetEventType    (MT7TraceEvent hEvent);
MT7TRACE float              MT7TraceGetEventX       (MT7TraceEvent hEvent);
MT7TRACE float              MT7TraceGetEventY       (MT7TraceEvent hEvent);
MT7TRACE unsigned int       MT7TraceGetEventTime    (MT7TraceEvent hEvent);
MT7TRACE MT7TraceTrace      MT7TraceGetEventTrace   (MT7TraceEvent hEvent);
MT7TRACE void               MT7TraceReleaseEvent    (MT7TraceEvent hEvent);

// Monitor/Poll API
MT7TRACE int    MT7TracePoll                (void);
MT7TRACE int    MT7TraceStartMonitor        (void);
MT7TRACE void   MT7TraceStopMonitor         (void);
MT7TRACE void   MT7TraceSetArrivalCallback  (MT7TraceCallback fnCallback,void * pvUserCode);
MT7TRACE void   MT7TraceSetUniversalCallback(MT7TraceCallback fnCallback,void * pvUserCode);

/******************************************************************************/
/* G L O B A L   M A C R O S                                                  */

#ifdef __cplusplus
}
#endif

#endif /* ifndef __MT7TRACE_H__ */
like image 764
felix Avatar asked Mar 22 '26 13:03

felix


1 Answers

Most likely the unbalanced stack is caused by using the wrong calling convention. Change your DllImport attribute:

[DllImport("MT7Trace.dll", CallingConvention=CallingConvention.Cdecl)]
like image 190
Jim Mischel Avatar answered Mar 24 '26 03:03

Jim Mischel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!