Jeg skal skrive et program, som snakker med et andet program igennem en DLL, og der er selvfølgelig et antal funktioner, som jeg kan skrive til, men jeg ved ikke nok om hvordan de skal bruges.
Stillede at andet spørgsmål om oversættelse af noget C++ kode, som fulgte med som eksempel. Fik det her svar:
Her er et eksemple på hvordan jeg kalder funktionerne i DLL'en: [DllImport("homeputer.dll", EntryPoint = "homeputer_SetWindowHandle", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool homeputer_SetWindowHandle(IntPtr WindowsHandle);
Nu skal jeg bare finde ud af hvordan jeg laver en pointer.
Mht StringBuilder: Strenge i c# er immutables, dvs når du skriver noget i stil med: string a = "abc"; a = a + "def"; så bliver a reelt nedlagt og genoprettet som 'abcdef'. Med andre ord, så medfører streng + streng en frygtelig masse allokering og deallokering af hukommelse. Det er ineffektivt (og en dødssynd ved web-udvikling).
Derfor findes der en 'hjælpeklasse' System.Text.StringBuilder som er effektiv til konkatenering af strenge.
Mht 'ref': Parametre kan overføres som reference parametre; dvs givet to funktioner: void foo1(int x) {x = 123;} void foo2(ref int x) {x = 123;} så er forskellen at foo1 IKKE ændrer ved parameteren; hvilket foo2 derimod gør. Dvs: int a = 1; foo1(a); // a er stadig 1 foo2(a); // nu er a 123!
Grunden til jeg foreslår du ændrer parametrene til 'ref string', er at det reelt giver et ekstra lag indirection i forhold til C++ kaldet. I 'gamle dage' med VB6, skulle man typisk lave det modsatte trick pga VB6's noget mystiske implementering internt af strenge.
StringBuilder har 'indbygget' lidt ekstra Marshall'ing funktionalitet, i forbindelse med p/invoke til en pointer til et char array.
Men altså - det aller-aller letteste ville nok være, hvis du gav os den oprindelige C deklaration til metoden homeputer_getObjIdx, hvis du har den nogen steder. Så ville vi være fri for at gætte os frem.
Here goes.... ................................. #include <dir.h> #include <string.h>
HINSTANCE DLL_Handle;
typedef INT _stdcall (*Thomeputer_InitDLL)(); typedef INT _stdcall (*Thomeputer_SetObjValName)(char*, char*); typedef INT _stdcall (*Thomeputer_GetObjValName)(char*, char*); typedef INT _stdcall (*Thomeputer_SetWindowHandle)(longword); typedef INT _stdcall (*Thomeputer_ChangeCount)(); typedef INT _stdcall (*Thomeputer_ChangedObjects)(char*); typedef INT _stdcall (*Thomeputer_ObjectCount)(); typedef INT _stdcall (*Thomeputer_GetObjIdx)(int, char*, char*);
C++ interfacet er IMHO et bufferoverrun der venter på at ske.
Hvorom det er, så prøv at sikre, at strengene du kalder med, inden kaldet fyldes med f.eks 254 spaces. Så vidt jeg kan se, så kan man ikke angive en buffer størrelse og man får heller ikke en tilbage, hvilket er MEGET uheldigt.
De første 5 linier smider Working Dir ind i s2. Så skiftes "\" ud med "/" og dll'ens navn lægges til. Til sidst smides værdien af s2 (som er stien til dll'en) ned i en c-streng, som så bruges som argument til dynamisk at load'e dll'en.
Alt det burde være transparent ifbm .Net DllImport.
Du siger det ikke virker helt. Hvad er fejlen? Får du en exception eller forkerte retur værdier eller ??
Og her er den exception jeg får... System.Runtime.InteropServices.SEHException: External component has thrown an exception. at ALMAX_TEST_2.Homeputer.homeputer_GetObjIdx(Int32 Index, String& ObjectName, String& ObjectValue) at ALMAX_TEST_2.MainWindow.WndProc(Message& Homeputer_Message) in T:\Program\ALMAX TEST 2\ALMAX TEST 2\MainWindow.cs:line 69
Linie 69 er: Homeputer.homeputer_GetObjIdx( Homeputer_Message.WParam.ToInt32(), ref ObjectName, ref ObjectValue);
-----------------------------------
Jeg har fået forslaget om at lave en catch, som ser sådan her ud: catch (System.Runtime.InteropServices.SEHException ex) { MessageBox.Show(ex.InnerExcepotion.ToString()); }
Det prøver jeg lige, så jeg kan få den inderste exception men her op, så du har mere at gå på =)
System.NullReferenceException: Object reference not set to an instance of an object. at ALMAX_TEST_2.MainWindow.WndProc(Message& Homeputer_Message) in T:\Program\ALMAX TEST 2\ALMAX TEST 2\MainWindow.cs:line 80 at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Det er rent gætteri; men jeg går ud fra at homeputer_GetObjIdx skal kaldes med et Index (på et object) og at du får udfyldt to string med navn og værdi. Lyder det nogenlunde rigtigt???
Her er den tysk vejlednings tekst, måske kan du så noget ud af den =)
homeputer_GetObjIdx(Index, Objektname, Objektwert) Mit dieser Funktion können Objektname und Objektwert für den angegebenen Index ermittelt werden. Der Index ist vom Typ integer, Objektname und Objektwert sind Pointer auf nullterminierte Strings. Aufrufparameter : Index, Objektname, Objektwert Rückgabewert: 1 Aufruf war erfolgreich, gültigen Werte in Objektname, Objektwert 0 Aufruf war nicht erfolgreich, keine gültigen Werte in Objektname, Objektwert Aufrufbeispiel in Delphi und C homeputer_GetObjIdx(Idx, ObjName, ObjValue)
Du får lige hovedteksten igen, men kørt igennem babelfish.
With this function object name and object value for the indicated index can be determined. The index is more integer of the type, object name and object value is pointers on zero-scheduled stringers. Call parameter: Index, object name, object value
Hver gang der sker en ændring i vinduet, som DLL har forbindelse til får jeg en winproc tilbage... med beskeden (message) WParam.
wparam = 0, hver gang uret tikker... lige gyldigt wparam = 1, Hver gang der sker en ændring i FHT modulet, som er det modul jeg er interesseret i =)
P.s: FHT står ikke har noget sætligt, det er bare et modul nummer/navn
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.