Code archives/Miscellaneous/Call dll at runtime (no not CallDLL).
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
Ok this is something I found on my HD, it's not that old just that I forgotten I've done it. Though I might as well share it with the community and with hopes that someone finds it usefull. So what does this do? Well it enables you to call dll functions during runtime. First thing you have todo is to include "CallDLL.bb" This file includes these functions. CBegin() - Allocate data and and prepares a call CEnd() - Free data and stuff CPushInt(Value%) - Push an int on the stack CPushFloat(Value#) - Push a float on the stack CPushString(Value$) - Push a string on the stack CPushBank(Value) - Push an allocated bank on the stack ComCallInt%(Func,Method) - Make a call to an com object interface returns an int CallInt%(Func) - Make a call to a func (ret value int) CallStr$(Func) - Same as above but returns a string CallFloat#(Func) - yeah yeah returns a float What you have to remember when pushing values to the stack is to do it like you would do in assembler. In the reverse order. This is because the first value you put on the stack is actually the last that is retrived. Lets for example make a function that displays the good old MessageBox. Lets take a peek on MessageBox function first though. int MessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType); Example: ----------------------------------------------------------- Include "CallDLL.bb" Function MessageBox(hWnd%,Text_$,Caption$,uType%) Local User32 = LoadDLL("User32.dll") ; LoadLibrary if User32 = 0 Then RuntimeError("MessageBox : Failed to load User32.dll") Local MsgBox = ProcDLL(User32,"MessageBoxA") ;GetProcAddress CBegin() CPushInt(uType) ;In the reverse order remeber? CPushString(Caption) CPushString(Text_) CPushInt(hWnd) ;Since MessageBox returns an int we'll use CallInt Local Ret = CallInt(Msgbox) CEnd() FreeDLL(User32) Return Ret End Function Print MessageBox(0,"This is" + Chr(13) + "a test","Info",0) WaitKey() ----------------------------------------------------------- You can also make calls to Com objects using ComCallInt function. So how do you do this? Well lets take a look at the IUnknown interface methods and some of the IDirect3D9 methods. (This is copied from d3d9.h) STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; STDMETHOD_(ULONG,AddRef)(THIS) PURE; STDMETHOD_(ULONG,Release)(THIS) PURE; STDMETHOD(RegisterSoftwareDevice)(THIS_ void* pInitializeFunction) PURE; STDMETHOD_(UINT, GetAdapterCount)(THIS) PURE; STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER9* pIdentifier) PURE; So lets say you make a call to Direct3D9Create create and it returns an interface address. And you want to make a call Release. Then all you have todo is to use ComCallInt, i.e. ComCallInt([Interface Address],8) So why 8? It's because it's the 3rd function in this interface. QueryInterface is on 0 (ComCallInt([Addr],0) AddRef is on 4 (ComCallInt([Addr],4) Release on 8 RegisterSoftware on 12 ... So on so forth, in other words [Address + Method * 4] (if you count QueryInterface as 0). Well thats pretty much all folks. Hope it made sense. And hope that the spacing isn't to f*cked up. Ohh and this is rather untested (tested on 2 different computers). So I take no responsibility of what this code might do to your computer and stuff. Oh and I forgot to add the decl file needed for the extremly simple directx9 test that are in the zip. (It creates an device and goes into fullscreen). So I'll just add it to the code field below. Oh and the blitzasm stuff is heavily based on Kevin Poole's stuff with my own additions. Have fun...or not :-P , hope someone find this usefull. Ahh well back to my wrestling match with Quaternions.... Download | |||||
.lib "d3d9.dll" Direct3DCreate9_%(SDK%):"Direct3DCreate9" |
Comments
None.
Code Archives Forum