Auf dll Funktionen zugreifen

  • GM 8

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Auf dll Funktionen zugreifen

    Hallo Leute,



    ich weiß nicht ob sich jemand damit auskennt, aber ich würde gerne mit dem game maker auf Variablen eines anderen Programms zugreifen (genauer: MS Flightsimulator). Da dies von Haus aus nicht geht, hat jemand eine dll (FSUIPC) geschrieben, über die es möglich ist alles mögliche aus dem Flugsimulator auszulesen. Dafür muss man nur eine entsprechende header datei und .lib datei zu seinem projekt (zB mit MS Visual Studio, das ich bisher dafür benutzt habe) includieren bzw. linken und dann kann man auf die Funktionen dieser dll zugreifen. Nun würde ich dies gern mit dem game maker verbinden bin mir aber ein wenig unschlüssig, inwiefern man das hinbekommen könnte...hat da vielleicht jemand einen Tip? Habe schon ein wenig mit Extensions experimentiert, komme da aber nicht richtig weiter.



    Gruß, Benny
  • Wenn die DLL nicht für den Game Maker geschrieben ist, dann wird es wohl nicht gehen.
    Du/Jemand könnte da aber versuchen eine DLL zu schreiben die die Funktion an diese DLL weiterleitet.
    Alles was du wissen willst steht hier: gm-d.de/help/hh_start.htm?414_00_dlls.html .
    wupto.net/ Nicht meine Seite!
    We love Koalas.

    GM-D-Spam-o-Meter: 32%
  • Hmm...okay...der für die .lib Datei verwendete Source Code ist öffentlich verfügbar und müsste dementsprechend dann wohl umgewandelt werden, wobei das glaub ich mein Können im Moment noch überschreitet :rolleyes: . Hier mal der c code für die Bibliothek:

    C-Quellcode

    1. /* IPCUSER.C User interface library for FSUIPC
    2. *******************************************************************************
    3. Started: 28th November 2000
    4. With acknowledgements to Adam Szofran (author of original FS6IPC).
    5. ******************************************************************************/
    6. #define LIB_VERSION 2002 // 2.002
    7. #define MAX_SIZE 0x7F00 // Largest data (kept below 32k to avoid
    8. // any possible 16-bit sign problems)
    9. #include "IPCuser.h"
    10. /******************************************************************************
    11. IPC client stuff
    12. ******************************************************************************/
    13. DWORD FSUIPC_Version = 0;
    14. DWORD FSUIPC_FS_Version = 0;
    15. DWORD FSUIPC_Lib_Version = LIB_VERSION;
    16. static HWND m_hWnd = 0; // FS6 window handle
    17. static UINT m_msg = 0; // id of registered window message
    18. static ATOM m_atom = 0; // global atom containing name of file-mapping object
    19. static HANDLE m_hMap = 0; // handle of file-mapping object
    20. static BYTE* m_pView = 0; // pointer to view of file-mapping object
    21. static BYTE* m_pNext = 0;
    22. /******************************************************************************
    23. FSUIPC_Close
    24. ******************************************************************************/
    25. // Stop the client
    26. void FSUIPC_Close(void)
    27. { m_hWnd = 0;
    28. m_msg = 0;
    29. if (m_atom)
    30. { GlobalDeleteAtom(m_atom);
    31. m_atom = 0;
    32. }
    33. if (m_pView)
    34. { UnmapViewOfFile((LPVOID)m_pView);
    35. m_pView = 0;
    36. }
    37. if (m_hMap)
    38. { CloseHandle(m_hMap);
    39. m_hMap = 0;
    40. }
    41. }
    42. /******************************************************************************
    43. FSUIPC_Open
    44. ******************************************************************************/
    45. // Start the client
    46. // return: TRUE if successful, FALSE otherwise
    47. BOOL FSUIPC_Open(DWORD dwFSReq, DWORD *pdwResult)
    48. { char szName[MAX_PATH];
    49. static int nTry = 0;
    50. BOOL fWideFS = FALSE;
    51. int i = 0;
    52. // abort if already started
    53. if (m_pView)
    54. { *pdwResult = FSUIPC_ERR_OPEN;
    55. return FALSE;
    56. }
    57. // Clear version information, so know when connected
    58. FSUIPC_Version = FSUIPC_FS_Version = 0;
    59. // Connect via FSUIPC, which is known to be FSUIPC's own
    60. // and isn't subject to user modificiation
    61. m_hWnd = FindWindowEx(NULL, NULL, "UIPCMAIN", NULL);
    62. if (!m_hWnd)
    63. { // If there's no UIPCMAIN, we may be using WideClient
    64. // which only simulates FS98
    65. m_hWnd = FindWindowEx(NULL, NULL, "FS98MAIN", NULL);
    66. fWideFS = TRUE;
    67. if (!m_hWnd)
    68. { *pdwResult = FSUIPC_ERR_NOFS;
    69. return FALSE;
    70. }
    71. }
    72. // register the window message
    73. m_msg = RegisterWindowMessage(FS6IPC_MSGNAME1);
    74. if (m_msg == 0)
    75. { *pdwResult = FSUIPC_ERR_REGMSG;
    76. return FALSE;
    77. }
    78. // create the name of our file-mapping object
    79. nTry++; // Ensures a unique string is used in case user closes and reopens
    80. wsprintf(szName, FS6IPC_MSGNAME1 ":%X:%X", GetCurrentProcessId(), nTry);
    81. // stuff the name into a global atom
    82. m_atom = GlobalAddAtom(szName);
    83. if (m_atom == 0)
    84. { *pdwResult = FSUIPC_ERR_ATOM;
    85. FSUIPC_Close();
    86. return FALSE;
    87. }
    88. // create the file-mapping object
    89. m_hMap = CreateFileMapping(
    90. (HANDLE)0xFFFFFFFF, // use system paging file
    91. NULL, // security
    92. PAGE_READWRITE, // protection
    93. 0, MAX_SIZE+256, // size
    94. szName); // name
    95. if ((m_hMap == 0) || (GetLastError() == ERROR_ALREADY_EXISTS))
    96. { *pdwResult = FSUIPC_ERR_MAP;
    97. FSUIPC_Close();
    98. return FALSE;
    99. }
    100. // get a view of the file-mapping object
    101. m_pView = (BYTE*)MapViewOfFile(m_hMap, FILE_MAP_WRITE, 0, 0, 0);
    102. if (m_pView == NULL)
    103. { *pdwResult = FSUIPC_ERR_VIEW;
    104. FSUIPC_Close();
    105. return FALSE;
    106. }
    107. // Okay, now determine FSUIPC version AND FS type
    108. m_pNext = m_pView;
    109. // Try up to 5 times with a 100mSec rest between each
    110. // Note that WideClient returns zeroes initially, whilst waiting
    111. // for the Server to get the data
    112. while ((i++ < 5) && ((FSUIPC_Version == 0) || (FSUIPC_FS_Version == 0)))
    113. { // Read FSUIPC version
    114. if (!FSUIPC_Read(0x3304, 4, &FSUIPC_Version, pdwResult))
    115. { FSUIPC_Close();
    116. return FALSE;
    117. }
    118. // and FS version and validity check pattern
    119. if (!FSUIPC_Read(0x3308, 4, &FSUIPC_FS_Version, pdwResult))
    120. { FSUIPC_Close();
    121. return FALSE;
    122. }
    123. // Write our Library version number to a special read-only offset
    124. // This is to assist diagnosis from FSUIPC logging
    125. // But only do this on first try
    126. if ((i < 2) && !FSUIPC_Write(0x330a, 2, &FSUIPC_Lib_Version, pdwResult))
    127. { FSUIPC_Close();
    128. return FALSE;
    129. }
    130. // Actually send the requests and get the responses ("process")
    131. if (!FSUIPC_Process(pdwResult))
    132. { FSUIPC_Close();
    133. return FALSE;
    134. }
    135. // Maybe running on WideClient, and need another try
    136. Sleep(100); // Give it a chance
    137. }
    138. // Only allow running on FSUIPC 1.998e or later
    139. // with correct check pattern 0xFADE
    140. if ((FSUIPC_Version < 0x19980005) || ((FSUIPC_FS_Version & 0xFFFF0000L) != 0xFADE0000))
    141. { *pdwResult = fWideFS ? FSUIPC_ERR_RUNNING : FSUIPC_ERR_VERSION;
    142. FSUIPC_Close();
    143. return FALSE;
    144. }
    145. FSUIPC_FS_Version &= 0xffff; // Isolates the FS version number
    146. if (dwFSReq && (dwFSReq != FSUIPC_FS_Version)) // Optional user specific FS request
    147. { *pdwResult = FSUIPC_ERR_WRONGFS;
    148. FSUIPC_Close();
    149. return FALSE;
    150. }
    151. *pdwResult = FSUIPC_ERR_OK;
    152. return TRUE;
    153. }
    154. /******************************************************************************
    155. FSUIPC_Process
    156. ******************************************************************************/
    157. BOOL FSUIPC_Process(DWORD *pdwResult)
    158. { DWORD dwError;
    159. DWORD *pdw;
    160. FS6IPC_READSTATEDATA_HDR *pHdrR;
    161. FS6IPC_WRITESTATEDATA_HDR *pHdrW;
    162. int i = 0;
    163. if (!m_pView)
    164. { *pdwResult = FSUIPC_ERR_NOTOPEN;
    165. return FALSE;
    166. }
    167. if (m_pView == m_pNext)
    168. { *pdwResult = FSUIPC_ERR_NODATA;
    169. return FALSE;
    170. }
    171. ZeroMemory(m_pNext, 4); // Terminator
    172. m_pNext = m_pView;
    173. // send the request (allow up to 9 tries)
    174. while ((++i < 10) && !SendMessageTimeout(
    175. m_hWnd, // FS6 window handle
    176. m_msg, // our registered message id
    177. m_atom, // wParam: name of file-mapping object
    178. 0, // lParam: offset of request into file-mapping obj
    179. SMTO_BLOCK, // halt this thread until we get a response
    180. 2000, // time out interval
    181. &dwError)) // return value
    182. { Sleep(100); // Allow for things to happen
    183. }
    184. if (i >= 10) // Failed all tries?
    185. { *pdwResult = GetLastError() == 0 ? FSUIPC_ERR_TIMEOUT : FSUIPC_ERR_SENDMSG;
    186. return FALSE;
    187. }
    188. if (dwError != FS6IPC_MESSAGE_SUCCESS)
    189. { *pdwResult = FSUIPC_ERR_DATA; // FSUIPC didn't like something in the data!
    190. return FALSE;
    191. }
    192. // Decode and store results of Read requests
    193. pdw = (DWORD *) m_pView;
    194. while (*pdw)
    195. { switch (*pdw)
    196. { case FS6IPC_READSTATEDATA_ID:
    197. pHdrR = (FS6IPC_READSTATEDATA_HDR *) pdw;
    198. m_pNext += sizeof(FS6IPC_READSTATEDATA_HDR);
    199. if (pHdrR->pDest && pHdrR->nBytes)
    200. CopyMemory(pHdrR->pDest, m_pNext, pHdrR->nBytes);
    201. m_pNext += pHdrR->nBytes;
    202. break;
    203. case FS6IPC_WRITESTATEDATA_ID:
    204. // This is a write, so there's no returned data to store
    205. pHdrW = (FS6IPC_WRITESTATEDATA_HDR *) pdw;
    206. m_pNext += sizeof(FS6IPC_WRITESTATEDATA_HDR) + pHdrW->nBytes;
    207. break;
    208. default:
    209. // Error! So terminate the scan
    210. *pdw = 0;
    211. break;
    212. }
    213. pdw = (DWORD *) m_pNext;
    214. }
    215. m_pNext = m_pView;
    216. *pdwResult = FSUIPC_ERR_OK;
    217. return TRUE;
    218. }
    219. /******************************************************************************
    220. FSUIPC_Read
    221. ******************************************************************************/
    222. BOOL FSUIPC_Read(DWORD dwOffset, DWORD dwSize, void *pDest, DWORD *pdwResult)
    223. { FS6IPC_READSTATEDATA_HDR *pHdr = (FS6IPC_READSTATEDATA_HDR *) m_pNext;
    224. // Check link is open
    225. if (!m_pView)
    226. { *pdwResult = FSUIPC_ERR_NOTOPEN;
    227. return FALSE;
    228. }
    229. // Check have space for this request (including terminator)
    230. if (((m_pNext - m_pView) + 4 + (dwSize + sizeof(FS6IPC_READSTATEDATA_HDR))) > MAX_SIZE)
    231. { *pdwResult = FSUIPC_ERR_SIZE;
    232. return FALSE;
    233. }
    234. // Initialise header for read request
    235. pHdr->dwId = FS6IPC_READSTATEDATA_ID;
    236. pHdr->dwOffset = dwOffset;
    237. pHdr->nBytes = dwSize;
    238. pHdr->pDest = (BYTE *) pDest;
    239. // Zero the reception area, so rubbish won't be returned
    240. if (dwSize) ZeroMemory(&m_pNext[sizeof(FS6IPC_READSTATEDATA_HDR)], dwSize);
    241. // Update the pointer ready for more data
    242. m_pNext += sizeof(FS6IPC_READSTATEDATA_HDR) + dwSize;
    243. *pdwResult = FSUIPC_ERR_OK;
    244. return TRUE;
    245. }
    246. /******************************************************************************
    247. FSUIPC_Write
    248. ******************************************************************************/
    249. BOOL FSUIPC_Write(DWORD dwOffset, DWORD dwSize, void *pSrce, DWORD *pdwResult)
    250. { FS6IPC_WRITESTATEDATA_HDR *pHdr = (FS6IPC_WRITESTATEDATA_HDR *) m_pNext;
    251. // check link is open
    252. if (!m_pView)
    253. { *pdwResult = FSUIPC_ERR_NOTOPEN;
    254. return FALSE;
    255. }
    256. // Check have spce for this request (including terminator)
    257. if (((m_pNext - m_pView) + 4 + (dwSize + sizeof(FS6IPC_WRITESTATEDATA_HDR))) > MAX_SIZE)
    258. { *pdwResult = FSUIPC_ERR_SIZE;
    259. return FALSE;
    260. }
    261. // Initialise header for write request
    262. pHdr->dwId = FS6IPC_WRITESTATEDATA_ID;
    263. pHdr->dwOffset = dwOffset;
    264. pHdr->nBytes = dwSize;
    265. // Copy in the data to be written
    266. if (dwSize) CopyMemory(&m_pNext[sizeof(FS6IPC_WRITESTATEDATA_HDR)], pSrce, dwSize);
    267. // Update the pointer ready for more data
    268. m_pNext += sizeof(FS6IPC_WRITESTATEDATA_HDR) + dwSize;
    269. *pdwResult = FSUIPC_ERR_OK;
    270. return TRUE;
    271. }
    272. /******************************************************************************
    273. End of IPCuser module
    274. ******************************************************************************/
    Alles anzeigen
  • Hmm.. kannst du mir vl die Links dazu schicken mit header files libs usw? evtl könnt ich ja was machen, müsste nicht unbedingt so ein riesen aufwand sein... hab zwar keine ahnung von c, aber gerade deswegen würd ich mir das mal gern anschaun..
    "das war meine letzte flamewar PM an dich ."
  • Ok, habs mir jetzt n bissl angeschaut.
    Prinzipiell kann die library 2 dinge machen: lesen und schreiben.
    Dazu gibst du eine Adresse im Speicher vom Flightsim an(Dazu musst du erstmal nachschauen, wo was abgespeichert ist im Memory) und liest bzw schreibst dann.
    Die Library definiert aber nirgendswo Konstanten oder ähnliches, mithilfe deren man wüsste, wo welche Variablen im Memory vom Flightsim zu finden sind.
    Im Sdk Zip File liegt ja auch noch so ein Pdf Dok bei, in dem die ganzen Adressen beschrieben werden.
    Man müsste also selber ein Mapping von Adressen mit ansprechenden Namen und den Datenstrukturen an den Adressen machen, und das ist einerseits zeitaufwändig, und andererseits müsste man auch testen können(hab kein Flightsim, kann also nicht testen).
    Es wäre sehr unschön, das direkt mit dem Gamemaker anzusprechen( du müsstest ne hexadezimale adresse angeben und die daten(die einzelnen bytes) in einer liste oder sowas abspeichern müssen...).
    Mit dabei im Sdk ist ja noch dieses Programm: FSInterrogate2std.exe
    mit dem sich n haufen Variablen managen lassen.
    Ich kanns nicht testen, da ich keinen Flightsim hab, aber wieso benutzt du nicht einfach dieses Programm?
    Gibts was spezielles, was du im GM anstellen willst?
    "das war meine letzte flamewar PM an dich ."
  • Hi...danke nochmal fürs ansehen...soweit ich es verstanden (und auch verwendet habe) ist dieses FS Interrogate nur dazu da, um die ganzen grafisch Adressen auszulessen und anzeigen zu lassen. Damit kann man dann beispielsweise per drag and drop ganz einfach Adressen suchen, die man im eigenen Programm ansprechen muss, um bestimmte Variablen auszulesen. Ich glaube sonst kann man das für nix anderes verwenden...ich habe mir aber schon gedacht, dass alles andere recht schwierig werden könnte.

    Ich habe da schon bestimmte Ideen, was ich vielleicht machen wollen würde, nur leider impliziert das, dass ich Daten aus dem Flusi auslesen müsste. Wie gesagt, ich habe ja auch schon diverse Sachen mit Visual Studio gemacht, wo alles nach includieren der im SDK enthaltenen library und ansprechen der entsprechenden hex adressen gefunzt hat, nur gerade der grafische Teil wäre mit GameMaker weitaus einfacher zu handeln, zumal man dann vielleicht sogar eine Action Library erstellen könnte und somit ganz leicht per drag and drop bestimmte Sachen auslesen/schreiben könnte ;) . Aber ohne das Testen zu können ist das natürlich Mist. Hab ich mir vielleicht auch einfach zu leicht vorgestellt :rolleyes: .

    Gruß, Benny
  • Naja, es gibt ja auch zb für C# eine Library bzw du könntest auch C++/CLI mit Windows Forms nutzen und ziemlich einfach ein GUI erstellen... im GM müsstest du erstmal Buttons und Textboxen & co programmieren...
    So wie ich gelesen hab, lassen sich mit dem Tool auch Variablen verändern.

    Grüssle
    "das war meine letzte flamewar PM an dich ."
  • Danke erstmal für deine Bemühungen...unter Umständen werde ich versuchen in C++ eine kleine App zu schreiben und damit dann Daten zwischen GameMaker und der dll auszutauschen. Mal sehen ob das klappt...hab mir da letzte Nacht was überlegt ;) .
    Gruß, Benny
  • Eine App ist unnötig, im Prinzip müssen nur die extern aufrufbaren Funktionen
    in Hinsicht auf Rückgabetypen und Parameter (Game Maker kann nur mit
    *char[] und double was anfangen bzw übergibt so alles) angepasst werden.
    Dann kann die dll mit den external_ Funktionen im Game Maker benutzt
    werden.
    ___________________________________________________________
    Beware of wild pointers
    ______Hinweis für Allergiker: Kann Spuren von Ironie enthalten_____