erklärt mir wer das wrappen ?



  • Hallo !!
    Ich müsste dringend c++ code (Kameratreiber) in ein c#-projekt einfügen.
    Ich blick nur einfach nicht durch wie eine wrapper-Klasse aussehen muss.
    Die mir bekannten Beispiele im Net sind mir zu kompliziert..
    Könnte mir jemand mal anhand einer absolut einfachen c++-Funktion zeigen, wie c++wrapper und c#-Aufruf aussehen müssen?

    ZB habe ich hier den Treiber in c++ eingebunden und lese nur char* getAPIVersion aus. Wie muss ich jetzt vorgehen, damit das als Wrapper-Klasse in c# funktioniert??

    #include "SR_API_WRAP.h"
    #pragma comment(lib,"F:\\testprogramme\\cpp\\PI_testsmartrayinclude\\SR_API.lib")
    #include "F:\\testprogramme\\cpp\\PI_testsmartrayinclude\\SR_API.h"
    CAMDESC* Cam1; CAMDESC* Cam2;
    int mesgType; int mesgdata1; int mesgdata2; char *mesg;
    SRPIXEL koordinate;
    SR_3DPOINT koordinate_world;
    char* apiver ="empty"; int Api_message;
    
    	apiver = SR_API_GetAPIVersion()
    


  • Servus,

    Stichwort: "PInvoke"

    Du kannst z.B. aus den Sources für dein Treiber eine unmanaged c++ DLL mit externen funktionen erstellen.

    Bsp. x.h:

    #define DECLDIR __declspec(dllexport)
    
    extern "C"
    {
       DECLDIR VOID Foo();
    }
    

    Bsp. x.cpp:

    #include "x.h"
    
    extern "C"
    {
        DECLDIR VOID Foo()
        {
            //MachWas!!!
        }
    }
    

    Bsp. x.cs:

    using System;
    using System.Runtime.InteropServices;
    
    namespace FooSpace
    {
        public class FooClass
        {
            public FooClass()
            {
            }
    
            [DllImport("x.dll", EntryPoint = "Foo")]
            internal static extern void Foo();
    
            private void DoFoo()
            {
                Foo();
            }
        }
    }
    

    Als einfaches Beispiel....

    gruß
    Hellsgore



  • Danke erstmal!
    Leider treten noch Fehler auf und ich versteh net warum. Die Redefinition von declspec schein nicht erkannt zu werden?

    f:\nc60_interface\sr_api_wrap\sr_api_wrap\SR_API_WRAP.h(11): error C2146: Syntaxfehler: Fehlendes ';' vor Bezeichner 'getVersion_Api'
    1>f:\nc60_interface\sr_api_wrap\sr_api_wrap\SR_API_WRAP.h(11): error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.
    1>f:\nc60_interface\sr_api_wrap\sr_api_wrap\SR_API_WRAP.h(11): error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.

    // SR_API_WRAP.h
    using namespace System;
    #include <string>
    #pragma comment(lib,"SR_API.lib")
    #include "SR_API.h"
    #define WRAP __declspec(dllexport)
    
    extern "C" 
    { 
    	WRAP string getVersion_Api();
    }
    
    #include "StdAfx.h"
    #include "SR_API_WRAP.h"
    // Dies ist die Haupt-DLL.
    extern "C" 
    { 
        WRAP string getVersion_Api(); 
        {
    		char* version;
    		std::string ver_str;
    		version = SR_API_GetAPIVersion();
    		ver_str = version;
    		return ver_str;
        } 
    }
    


  • @ghostwhisperer:
    Ich nehme an, dass deine API schon in einer DLL vorliegt (SR_API.dll). Korrekt?
    Dann musst Du nicht extra eine neue DLL machen nur um zu Wrappen!!!

    Benutze einfach den P/Invoke Mechanismus direkt mit der DLL.
    In der Header Datei SR_API.h findest Du die nötigen Deklarationen.

    Simon

    Edit:
    Das Tool "P/Invoke Interop Assistent" hilft Dir die nötigen C# Deklarationen ([DllImport...]) zu erstellen: http://clrinterop.codeplex.com/releases/view/14120



  • theta schrieb:

    @ghostwhisperer:
    Ich nehme an, dass deine API schon in einer DLL vorliegt (SR_API.dll). Korrekt?
    Dann musst Du nicht extra eine neue DLL machen nur um zu Wrappen!!!
    Benutze einfach den P/Invoke Mechanismus direkt mit der DLL.
    In der Header Datei SR_API.h findest Du die nötigen Deklarationen.
    Simon
    Edit:
    Das Tool "P/Invoke Interop Assistent" hilft Dir die nötigen C# Deklarationen ([DllImport...]) zu erstellen: http://clrinterop.codeplex.com/releases/view/14120

    Hallo theta !
    Wenn ich das richtig verstehe, kann ich in c# keine c++ Libs und Header einbinden richtig??
    Die SR_API besteht aus Header, DLL und Lib und zusätzlich einer SR_API_Parameter.h.
    Deswegen dachte ich, dass mir nur übrigbleibt indirekt einzubinden, über c++ wrapper-dll:
    Ich muss zuerst die im Header angegebenen Structs aus SR_API.h im Programm instanzieren die zudem mit vielen weiteren Structs aus der Parameter.h zusammenhängen. Die Structs benötige ich als Parameter für die eigentlichen Funktionen der DLL. Hinzu kommt, dass in der SR_API.h die Funktionsaufrufe mit LIBCALL funktionieren.
    Also denk ich, ich muss in wrapper-Prog die Funktionsaufrufe schachteln UND die Structs so auflösen, dass ich die Werte in nachgebaute Structs in c# übergeben kann.
    Oder gehts auch anders? Nach meinen Recherchen nicht..

    MFG



  • Lies dir die Antwort von theta nochmal durch. Da steht alles drin, was du brauchst.



  • @ghostwhisperer
    Erstmal beachten, was theta geschrieben hat.

    Hast du denn eine fertige DLL mit "Extern" deklarierten Methoden die du aufrufen kannst? Dann lese nochmal über die Antwort von theta.

    Allerdings habe ich es so verstanden, dass du nur die "Sources + Lib" hast. Dann ist deine Überlegung zum weiteren Vorgehen richtig. Du schaust dir an, wie die einzelnen Methoden aufgerufen werden und reichst sie in deiner "Wrapper-Schicht" durch.

    Structs müssen nicht aufgelöst/konvertiert/etc. werden, solange diese nicht komplex sind. Mit komplex meine ich, verschachtelte "unions" etc. Diese Structs kannst du in deinem C# Aufrufer nachbauen. Gibts einige Tuts dazu, wie man soetwas macht. Ist alles kein Hexenwerk.

    gruß
    Hellsgore



  • OK jetzt versteh ich, was ich mit nem Fremdprogramm soll. Tolles Prog, werds weiterempfehlen! Ich hab den Header übersetzen lassen und daraus ne Klasse gemacht. Die API wird richtig gefunden und die einfachste Funktion GetVersion funzt.
    Hat aber noch 1 Schwierigkeit. Die fürchterlich verschachtelten Structs sind alle übersetzt. Aber das Marshalling ist überfordert:

    Eine nicht behandelte Ausnahme des Typs "System.Runtime.InteropServices.MarshalDirectiveException" ist in mscorlib.dll aufgetreten.
    Zusätzliche Informationen: "parameter #1" kann nicht gemarshallt werden: Interne Einschränkung: Die Struktur ist zu komplex oder zu groß
    

    Das wird IMMER WIEDER auftreten, da die Struktur CamDesc der Kameradescriptor für die Steuerung UND Datenverwaltung ist.

    Hat jemand eine Idee ? Oder doch einziger Ausweg das ganze zu wrappen und den ganzen Kram zu kleinen Krümeln zu zerbröseln?

    MFG !!



  • Zeig mal den "struct CamDesc" und google mal nach "pinvoke struct c#". Dort wird dir gezeigt wie man Structs richtig "marshalled".

    BTW. ich hab das Tool mal ausprobiert, ist ein nettes Hilfsmittel. Allerdings sollte man sich trotzdem mit dem Thema beschäftigen, damit man weiß was passiert und warum man es so machen sollte.



  • Hellsgore schrieb:

    Zeig mal den "struct CamDesc" und google mal nach "pinvoke struct c#". Dort wird dir gezeigt wie man Structs richtig "marshalled".

    BTW. ich hab das Tool mal ausprobiert, ist ein nettes Hilfsmittel. Allerdings sollte man sich trotzdem mit dem Thema beschäftigen, damit man weiß was passiert und warum man es so machen sollte.

    Hi! Ich hab mir alles angesehen, um die Unterschiede zu verstehen. Und gegoogelt hatte ich schon. Hab nur nicht alles verstanden..
    Hier ALLE beteiligten (Original-)Structs. Ist aber recht viel und tief geschachtelt (btw. dies ist ein Treiber einer Firma. Kann also nicht geändert werden):
    Inhalt von Camdesk:

    typedef struct{
    	int cam_index;
    	char name[260];
    	char IPAdr[17];		// IP Adr String "192.168......
    	unsigned short portnum;
    	int command;
    	unsigned char header[HEADERSIZE_USER];
    	void* pcamdata;
    	int camdatasize;
    	int dataavailable;
    	int connectionstate;
    	int tcp_handle;
    	int active;
    	int alive_time;
    	int archiv_active;
    	int archiv_handle;
    	void *lut;
    	void *usercbf; //=cbf(CAMDESC* cd)
    	int digio_out[4];
    	int digio_in[4];
    	int laser_status;
    	int laserlight;
    	int fps;
    	float Temp;
    	int running;
    	PARAM cpar;
    } CAMDESC;
    

    Inhalt von PARAM:

    typedef struct{
    	char Bezeichnung[256];
    	char Description[2048];   
    	MODUL Modul[50];
    	char fillbytes0[2048];  
    	int AnzahlModule;
    	M1 m1[2];
    	char fillbytes1[2048];
    	M2 m2[2];
    	char fillbytes2[2034];//2036; 2044
    	M3 m3[2];
    	char fillbytes3[2044];
    	M4 m4[2];
    	char fillbytes4[2048];
    	M5 m5[2];
    	char fillbytes5[2040];
    	M6 m6[2];
    	char fillbytes6[1944];	//2048 - 2x(2x10) - 2x(2x8) - 2x(2x8)       
    	M7 m7[2]; 
    	char fillbytes7[2044];
    	M8 m8[2];
    	char fillbytes8[2048];
    	M9 m9[2];   
    	char fillbytes9[2048];
    	M10 m10[2];     
    	char fillbytes10[2048];
    	M11 m11[2]; 
    	char fillbytes11[2048];
    	M12 m12[2];
    	char fillbytes12[1916];
    	M13 m13[2];
    	char fillbytes13[2048];
    	M14 m14[5];
    	char fillbytes14[2048]; 
    	M15 m15[5];
    	char fillbytes15[2048]; 
    	M16 m16[5];
    	char fillbytes16[2048]; 
    	M17 m17[5];
    	char fillbytes17[2048]; 
    	M18 m18[1];
    	char fillbytes18[2043];	 //2047
    	M90 m90[10];
    	char fillbytes90[2048];
    	M80 m80[1];   
    	char fillbytes80[2048];
    	M99 m99[2];   
    	char fillbytes99[12]; //16-1*int slope = 12
    	char Version[64];
    }PARAM;
    

    Die structs Modul, M1-99 usw:

    typedef struct
    {
    	double WAB;      //Winkel zw A B
    	double WAB_X;    //Drehpunkt X
    	double WAB_Y;    //Drehpunkt Y
    	double off_X;		 //Verschiebung X
    	double off_Y;		 //Verschiebung Z
    	double scale;		 // Skalierungung NUR Rückgabewert !!!
    	double scale_X;	 // X - scale : entlang der Laserlinie
    	double scale_Y;	 // Y - scale : Abstand zum Sensor (Höhe)
    	double negX;     // SmartRay pos X == Arnold neg X
    	double WB;       // Winkel der SmartRay X Koord zu X-Achse
    	double negY;		 // SmartRay nahe Sensor kleiner Wert = Arnold großer wert
    } COORD_TRANS_PARM;
    
    typedef struct
    {
    	double A1X; //A - SmartRay Kalib Koordinaten
    	double A1Y;
    	double A2X;
    	double A2Y;
    
    	double B1X; // B- Customer soll Koordinaten
    	double B1Y;
    	double B2X;
    	double B2Y;
    } REF_TRANS_POINTS;
    
    #define MODULNAMESIZE	256
    #define PARREFNAMESIZE	256
    typedef struct{
    	char name[MODULNAMESIZE];
    	char methodname[MODULNAMESIZE];
    	int  methodcode; // identifier der Methode entsprechend Modulbibliothek
    	char nextname[MODULNAMESIZE];
    	char result[10][PARREFNAMESIZE];
    	int resultoffset[10];
    	int resultsize;
    	int inst;
    }MODUL;
    typedef struct{
    	short startx;
    	short starty;
    	short width;
    	short height;
    	int  beli_kurz;
    	char bitwahl;
    	char aufloesung;
    	char readoutspeed;
    	char datavaliddelay;
    	char wrreq_delay;
    	char dummy;
    	short dummy2;
    }M1;
    typedef struct{
    	unsigned char threshold;
    	unsigned char threshold_long; //tresh für doppelbeli lange beliz. 
    	char reflexfilter;
    	char profilswitch;
    	unsigned short profilerate;  
    	unsigned short minNenner;
    	unsigned short reflexsearch;
    	unsigned char datamode;
    	unsigned char dummy;   //ex OberesLinkesEckWeg im Auswertebereich
    }M2;
    
    // Pars Method3 ACQUIRE (HW Datastream)
    typedef struct{
    	char subject;
    	char mode;
    	char dummy; //ex: camsel;  //2D Bildübertragung Select 0: Cam A  1: CamB  
    	short dummy2;// num_of_images
    	short num_of_profiles;
    	char active;
    }M3;
    
    // Pars Method4 GET_NEXT_LINE (SW Sdram Ringspeicher management)
    typedef struct{
      char width[256];
      unsigned char mode;
      unsigned short step[8];
      char nextmod[8][MODULNAMESIZE];
    }M4;
    
    // Pars Method5 PROFILE_TRACKING (HW ROI_Nachfuehrung)
    typedef struct{
      char active;
      char search_ymin[PARREFNAMESIZE];
      char search_ymax[PARREFNAMESIZE];
      unsigned short step;
      unsigned char mode;
      short offset;
      unsigned short maxjump;
      unsigned short minAnzVals;
    }M5;
    
    // Pars Method6 DOUBLE_EXPOSURE (HW Doppelbelichtung)
    typedef struct{
    	unsigned char active;  	//bit[0]: Doppelbeli activ; 			bit[1]: Non Zero 
    													//bit[2]: _kurz Regelung activ; 	bit[3]: _lang Regelung activ
    	unsigned char dummy1;
    	short dummy2;
    	int beli_kurz;
    	int beli_lang;
    										// neu Parameter für BelichtungszeitRegelung 2009-03-02:TA
    
    	unsigned short beli_kurz_min;	 //untere Regelgrenze
    	unsigned short beli_kurz_max;	 //obere  Regelgrenze
    	unsigned short beli_kurz_maxstep;     //maximale Regelschrittweite
    	unsigned short beli_kurz_sumgreyset; //RegelSollWert  
    	unsigned short beli_kurz_dummy;	 //Reserve
    
    	unsigned short beli_lang_min;	 //untere Regelgrenze
    	unsigned short beli_lang_max;	 //obere  Regelgrenze
    	unsigned short beli_lang_maxstep;    //maximale Regelschrittweite
    	unsigned short beli_lang_sumgreyset; //RegelSollWert
    	unsigned short beli_lang_dummy;  //Reserve
    
    	unsigned short beli_kurz_roiStart;   //ROI Start für Regelung innerhalb der Imager width
      unsigned short beli_kurz_roiStop;    //ROI Ende für Regelung innerhalb der Imager width
      unsigned short beli_kurz_colSumGreyThresh;  //Grauwert-Schwell über der ein Spalte der LL als hell gezählt wird
      unsigned short beli_kurz_colCntThresh;      //RegelSollWert Zahl der LL-hellen Spalten
    
      unsigned short beli_lang_roiStart;   //ROI Start für Regelung innerhalb der Imager width
      unsigned short beli_lang_roiStop;    //ROI Ende für Regelung innerhalb der Imager width
      unsigned short beli_lang_colSumGreyThresh;  //Grauwert-Schwell über der ein Spalte der LL als hell gezählt wird
      unsigned short beli_lang_colCntThresh;      //RegelSollWert Zahl der LL-hellen Spalten
    
    	unsigned short beli_numProfilesValid; //11bit, Anzahl gültiger Profile (Profil mit mehr als 16 Punkte) dann startet die Regelung
    
    	unsigned short spare[7];
    }M6;
    
    // Pars Method7 CORRELATOR (HW)
    typedef struct {
        unsigned short refprofillaenge;
        unsigned short pruefstartpos;
        unsigned short pruefendpos;
        char step;
        char refprofilefile[512];
    	short minbestval;
    }M7;
    
    // Pars Method8 2D_HIGHPASS (HW)
    typedef struct {
    	unsigned char active;
    	unsigned char dummy;
      unsigned short filtersize_x;
      unsigned short filtersize_y;
    }M8;
    
    // Pars Method9 GET_AVERAGE_DISTANCE (SW)
    typedef struct{
      char channel;
    	char dummy;
      unsigned short command;
    }M9;
    
    // Pars Method10 TIMESTAMP_GENERATOR (HW)
    typedef struct{
      char runmode;
      char countmode;
    }M10;
    
    // Pars Method11 GET_ERROR_STATUS (SW/HW)
    typedef struct{
      char channel;
      unsigned short command;
    }M11;
    
    // Pars Method12 PROFILTRIGGER (SW)
    typedef struct{
      char mode;
      unsigned short linedelay;
      char pcondition[PARREFNAMESIZE];
      char pdata[PARREFNAMESIZE];
      char nextmod[PARREFNAMESIZE]; 
      char pnullstelle[64];
      unsigned short minNullstellen;
    }M12;
    
    // Pars Method13 CALCULATOR (SW)
    typedef struct{
      char mode;
      char inputa[PARREFNAMESIZE];
      char inputb[PARREFNAMESIZE];
    }M13;
    
    // Pars Method14 COMPARE (SW)
    typedef struct{
      char mode[8];
      char inputa[8][PARREFNAMESIZE];
      char inputb[8][PARREFNAMESIZE];
    }M14;
    
    // Pars Method15 GET_VAL (SW)
    typedef struct{
      char data[8][PARREFNAMESIZE];
      int offset[8];
      char size[8];
    }M15;
    
    // Pars Method16 LOGIC (SW)
    typedef struct{
      char mode[3];
      char inputa[PARREFNAMESIZE];
      char inputb[PARREFNAMESIZE];
      char inputc[PARREFNAMESIZE];
      char inputd[PARREFNAMESIZE];
    }M16;
    
    // Pars Method17 READ_INPUT (SW)  
    typedef struct{
      char active[3];
      char condition[3];
      char nextmod[3][MODULNAMESIZE];
      char channel;
      unsigned short command;
    }M17;
    
    // Pars Method18 TRIGGER_SETUP (HW)
    typedef struct{
    	char mode;
    	unsigned char triggercnt;
    	char inputselect;
    	unsigned char triggerfrq;
    	unsigned char triggeroffset;
    	char dummy;
    	short dummy2;
    }M18;
    
    // Pars Method80 MODUL_Mercedes (HW)
    typedef struct {
        unsigned char threshold;
    		unsigned char dummy;
    		unsigned short dummy2;
        int buffersize;
    }M80;
    
    // Pars Method90 TCP_SEND (SW Send TCP Data)
    typedef struct{
      char channel;
      unsigned short command;
      unsigned char reserved; 
      char width[PARREFNAMESIZE];
      char pdata[PARREFNAMESIZE];
      char roi_startx[PARREFNAMESIZE];
      char roi_starty[PARREFNAMESIZE];
      char roi_width[PARREFNAMESIZE];
      char roi_height[PARREFNAMESIZE];
    }M90;
    
    // Pars Method99 CMOS_SETUP_LOW (HW Ibis)
    typedef struct{
    	short startx;
    	short starty;
    	short width;
    	short height;
    	int beli_kurz; 
    	char modulusx;
    	char modulusy;
    	char gain;
    	char offset_raw;
    	char offset_fine;
    	char datavaliddelay;
    	char gamma;
    	unsigned char laserctrl;// unused; ist jetzt eigene Funktion
    	int  slope;
    }M99;
    


  • Und das ist mal nur die Übersetzung von CamDesc:

    [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet = System.Runtime.InteropServices.CharSet.Ansi)]
        public struct CAMDESC
        {
            public int cam_index;
            [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 260)]
            public string name;
            [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 17)]
            public string IPAdr;
            public ushort portnum;
            public int command;
            [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 9)]
            public string header;
            public System.IntPtr pcamdata;
            public int camdatasize;
            public int dataavailable;
            public int connectionstate;
            public int tcp_handle;
            public int active;
            public int alive_time;
            public int archiv_active;
            public int archiv_handle;
            public System.IntPtr lut;
            public System.IntPtr usercbf;
            [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = System.Runtime.InteropServices.UnmanagedType.I4)]
            public int[] digio_out;
            [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = System.Runtime.InteropServices.UnmanagedType.I4)]
            public int[] digio_in;
            public int laser_status;
            public int laserlight;
            public int fps;
            public float Temp;
            public int running;
            /// PARAM->Anonymous_78cf3d06_3dc4_4201_9042_f198dd9034b7
            public PARAM cpar;
        }
    


  • Ich würde Schritt für Schritt vorgehen und mit etwas einfachen anfangen - z.B. die Version abfragen.



  • theta schrieb:

    Ich würde Schritt für Schritt vorgehen und mit etwas einfachen anfangen - z.B. die Version abfragen.

    Habe ich schon ! GetApiVersion funktioniert, die DLL wird bis dato richtig angesprochen. Aber GetApiVersion ist die einzige(!) Funktion die ohne CamDesc auskommt. Der nächste Schritt wäre API_Init(int (*userCB_StatusMessage) (STATUS_MSG_ARGLST)), sicherheitshalber explizit gefolgt von API_Exit(). Die Agumentenliste für den Callback in Init enhält bereits CamDesk.
    Das wurde so c# übersetzt:

    /// STATUS_MSG_ARGLST -> CAMDESC* cd, int msgType, int msgdata1, int msgdata2, char *msg
            /// Error generating expression: Expression is not parsable.  Treating value as a raw string
            public const string STATUS_MSG_ARGLST = "CAMDESC* cd, int msgType, int msgdata1, int msgdata2, char *msg";
     /// Return Type: int
        ///cd: CAMDESC*
        ///msgType: int
        ///msgdata1: int
        ///msgdata2: int
        ///msg: char*
        public delegate int Anonymous_0f4c62be_b627_4c7f_8bdf_1f94d68ecc01(ref CAMDESC cd, int msgType, int msgdata1, int msgdata2, System.IntPtr msg);
    /// Return Type: char*
            [System.Runtime.InteropServices.DllImportAttribute("SR_API.dll", EntryPoint = "SR_API_GetAPIVersion", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
            public static extern System.IntPtr SR_API_GetAPIVersion();
            /// Return Type: int
            ///userCB_StatusMessage: Anonymous_0f4c62be_b627_4c7f_8bdf_1f94d68ecc01
            [System.Runtime.InteropServices.DllImportAttribute("SR_API.dll", EntryPoint = "SR_API_Init", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
            public static extern int SR_API_Init(Anonymous_0f4c62be_b627_4c7f_8bdf_1f94d68ecc01 userCB_StatusMessage);
            /// Return Type: int
            [System.Runtime.InteropServices.DllImportAttribute("SR_API.dll", EntryPoint = "SR_API_Exit", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
            public static extern int SR_API_Exit();
    

    Mein bisheriges Test-Programm dazu (ist die Verwendung des delegaten des übersetzten Callback so richtig??):

    using SRAPIHTRANSLATION;
    namespace testapitranslation
    {
        public partial class Form1 : Form
        {
                SRAPIHTRANSLATION.CAMDESC Cam1 = new SRAPIHTRANSLATION.CAMDESC(); // MECKERT NICHT(!)
                SRAPIHTRANSLATION.CAMDESC Cam2 = new SRAPIHTRANSLATION.CAMDESC(); // MECKERT NICHT(!)
    
            static int MESSAGEHandler(ref CAMDESC cd, int msgType, int msgdata1, int msgdata2, System.IntPtr msg)
            {
                int haltepunkt; // NUR EIN TEST
                haltepunkt = 5;
                return haltepunkt;
            } // MECKERT BIS HIERHER NICHT
            Anonymous_0f4c62be_b627_4c7f_8bdf_1f94d68ecc01 MSGHandler = MESSAGEHandler; // MECKERT BIS HIERHER NICHT
            //public Form1()
            private void button1_Click(object sender, EventArgs e)
            {
                string Version;
                int Eventint; 
                Version = Marshal.PtrToStringAnsi(SRAPIHTRANSLATION.NativeMethods.SR_API_GetAPIVersion()); //funzt
    textBox1.Text = Version; // funzt
                Eventint = SRAPIHTRANSLATION.NativeMethods.SR_API_Init(MSGHandler); //funzt nicht marshalling sagt was von zu grosser struct
                Eventint = SRAPIHTRANSLATION.NativeMethods.SR_API_Exit();
                        }
        }
    }
    

    JEMAND NE IDEE??



  • Hallo !!
    Hat jemand ne Idee wie man das Problem lösen könnte ??

    Bringt es was, wenn ich alle Structs mit EXPLIZIT und Fieldoffset versehe??

    DANKE !!


Anmelden zum Antworten