linus Posted July 15, 2010 Share Posted July 15, 2010 I am completely stucked with a wrapper function for a .dll (I swear I read the au3 help over and over, searched the forum, so maybe somebody can tell me if I am to blind or if this is not possible at all?): I want to pass data to a C-function which takes it as a struct ("prop"), then access it via the struct field names (e.g. "prop.direction_x"): IParticleEmitter * DLL_EXPORT IrrAddParticleEmitter( IParticleSystemSceneNode* ps, IRR_PARTICLE_EMITTER prop ) { IParticleEmitter* em = ps->createBoxEmitter( core::aabbox3d<f32>(prop.min_box_x,prop.min_box_y,prop.min_box_z,prop.max_box_x,prop.max_box_y,prop.max_box_z), core::vector3df(prop.direction_x,prop.direction_y,prop.direction_z), prop.min_paritlcles_per_second,prop.max_paritlcles_per_second, ... So I pass a dllstruct for the "prop" to this function: $struct = "float min_box_x;float min_box_y;float min_box_z;float max_box_x;float max_box_y;float max_box_z;" & _ "float direction_x;float direction_y;float direction_z;uint min_paritlcles_per_second;uint max_paritlcles_per_second;" & _ "int min_start_color_red;int min_start_color_green;int min_start_color_blue;" & _ "int max_start_color_red;int max_start_color_green;int max_start_color_blue;" & _ "uint min_lifetime;uint max_lifetime;" & _ "float min_start_sizeX;float min_start_sizeY;float max_start_sizeX;float max_start_sizeY;int max_angle_degrees" $EmitterStruct = DllStructCreate($struct) DllStructSetData($EmitterStruct, "min_box_x", $f_MinBoxX) DllStructSetData($EmitterStruct, "min_box_y", $f_MinBoxY) DllStructSetData($EmitterStruct, "min_box_z", $f_MinBoxZ) DllStructSetData($EmitterStruct, "max_box_x", $f_MaxBoxX) DllStructSetData($EmitterStruct, "max_box_y", $f_MaxBoxY) DllStructSetData($EmitterStruct, "max_box_z", $f_MaxBoxZ) DllStructSetData($EmitterStruct, "direction_x", $f_DirectionX) DllStructSetData($EmitterStruct, "direction_y", $f_DirectionY) DllStructSetData($EmitterStruct, "direction_z", $f_DirectionZ) DllStructSetData($EmitterStruct, "min_paritlcles_per_second", $i_MinParticlesPerSecond) DllStructSetData($EmitterStruct, "max_paritlcles_per_second", $i_MaxParticlesPerSecond) DllStructSetData($EmitterStruct, "min_start_color_red", $i_MinStartRed) DllStructSetData($EmitterStruct, "min_start_color_green", $i_MinStartGreen) DllStructSetData($EmitterStruct, "min_start_color_blue", $i_MinStartBlue) DllStructSetData($EmitterStruct, "max_start_color_red", $i_MaxStartRed) DllStructSetData($EmitterStruct, "max_start_color_green", $i_MaxStartGreen) DllStructSetData($EmitterStruct, "max_start_color_blue", $i_MaxStartBlue) DllStructSetData($EmitterStruct, "min_lifetime", $i_MinLifetime) DllStructSetData($EmitterStruct, "max_lifetime", $i_MaxLifetime) DllStructSetData($EmitterStruct, "max_angle_degrees", $i_MaxAngle) DllStructSetData($EmitterStruct, "min_start_sizeX", $f_MinStartSizeX) DllStructSetData($EmitterStruct, "min_start_sizeY", $f_MinStartSizeY) DllStructSetData($EmitterStruct, "max_start_sizeX", $f_MaxStartSizeX) DllStructSetData($EmitterStruct, "max_start_sizeY", $f_MaxStartSizeY) $result = DllCall($_irrDll, "ptr:cdecl", "IrrAddParticleEmitter", "ptr", $h_ParticleSystem, "ptr", $EmitterStruct) The struct itself looks absolutely ok for me, but it seems the dll-function cannot read the passed data. Is this because of the accessing way of the C-function, or have I simply missed something? Thanks in advance ... Link to comment Share on other sites More sharing options...
trancexx Posted July 15, 2010 Share Posted July 15, 2010 ...or have I simply missed something?Pointer. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
linus Posted July 15, 2010 Author Share Posted July 15, 2010 Nice short answer - but I still cannot see a light If you mean: $result = DllCall($_irrDll, "ptr:cdecl", "IrrAddParticleEmitter", "ptr", $h_ParticleSystem, [b]"ptr", dllstructgetptr($EmitterStruct)[/b]) Was one of the things I tried this night without success ... Link to comment Share on other sites More sharing options...
trancexx Posted July 15, 2010 Share Posted July 15, 2010 (edited) Try something like this: $aCall = DllCall($_irrDll, "ptr:cdecl", "IrrAddParticleEmitter", "ptr*", 0, "ptr", DllStructGetPtr($EmitterStruct)) ;...here you check errors and then... $hPossiblyWhatYouWant = $aCall[1] Or depending what $h_ParticleSystem is (but you say you already tried):$aCall = DllCall($_irrDll, "ptr:cdecl", "IrrAddParticleEmitter", "handle", $h_ParticleSystem, "ptr", DllStructGetPtr($EmitterStruct)) Or: $aCall = DllCall($_irrDll, "ptr:cdecl", "IrrAddParticleEmitter", "ptr*", $h_ParticleSystem, "ptr", DllStructGetPtr($EmitterStruct)) Edited July 16, 2010 by trancexx ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
linus Posted July 16, 2010 Author Share Posted July 16, 2010 (edited) ... think you mean$result = DllCall($_irrDll, "ptr:cdecl", "IrrAddParticleEmitter", "ptr", $h_ParticleSystem, "ptr*", DllStructGetPtr($EmitterStruct))instead of ..., "ptr*", 0, ...but also creating a runtime error after some time. Rest of script should be without problems, so I bet on the struct parameter ... Do you know if a dll can read the dllstruct via "structName.Membername" as quoted in my first post?Or:Not really - $h_ParticleSystem is already a pointer. Other functions in script use it the same way (but without a dllstruct) without crash. Commenting out the evil "IrrAddParticleEmitter" (then a default emitter is used) works fine ... Edited July 16, 2010 by linus Link to comment Share on other sites More sharing options...
trancexx Posted July 16, 2010 Share Posted July 16, 2010 (edited) Do you know if a dll can read the dllstruct via "structName.Membername" as quoted in my first post?Structure is just a memory space (filled or not) that you provide/make.Accessing structure is other name for reading (binary) data at specific address.Dot operator in c(++) is used to access data members.Three sentences from the above make your question sound weird actually. Edited July 16, 2010 by trancexx ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
linus Posted July 16, 2010 Author Share Posted July 16, 2010 ... make your question sound weird actually.I know I know ... But after anatomising && surrounding the problem it's beginning to run out of my logic ... - also I agree to all of your three sentences Time to take a step back and rethink it tomorrow. Hope it's none of those strange side effect things ...Nevertheless, thanks! Link to comment Share on other sites More sharing options...
linus Posted September 24, 2010 Author Share Posted September 24, 2010 Just to make my own "weird" question more clear - and maybe save others from running into the complete wrong direction: If having a dll function like IParticleEmitter * DLL_EXPORT IrrAddParticleEmitter( IParticleSystemSceneNode* ps, IRR_PARTICLE_EMITTER prop ) where IRR_PARTICLE_EMITTER is a struct, then using a pointer seems not really to be a solution, because function is expecting the struct BY VALUE, not by reference. Finally I got it working by passing simply every struct member as sequence: DllCall($_irrDll, "ptr:cdecl", "IrrAddParticleEmitter", "UINT_PTR", $particleSystem, _ "float", -7, "float", 0, "float", -7, "float", 7, "float", 1, "float", 7, "float", 0, "float", 0.04, "float", 0, _ "UINT", 80, "UINT", 100, "int", 255, "int", 255, "int", 255, "int", 255, "int", 255, "int", 255, "UINT", 800, "UINT", 2000, _ "float", 15, "float", 15, "float", 15, "float", 15, "int", 15) Link to comment Share on other sites More sharing options...
AndyG Posted September 24, 2010 Share Posted September 24, 2010 Yes, sometimes it is not understandable how the parameters should be "transfered into the function". In this case (something is going wrong with the dll-call) i always start a debugger/disassembler and....have a look how the function is called and which parameters are expected: expandcollapse popup.text:1002B990 public IrrAddParticleEmitter .text:1002B990 IrrAddParticleEmitter proc near .text:1002B990 .text:1002B990 var_5C = dword ptr -5Ch .text:1002B990 var_58 = dword ptr -58h .text:1002B990 var_54 = dword ptr -54h .text:1002B990 var_44 = dword ptr -44h .text:1002B990 var_40 = dword ptr -40h .text:1002B990 var_3C = dword ptr -3Ch .text:1002B990 var_38 = dword ptr -38h .text:1002B990 var_34 = dword ptr -34h .text:1002B990 var_30 = dword ptr -30h .text:1002B990 var_24 = dword ptr -24h .text:1002B990 var_20 = dword ptr -20h .text:1002B990 var_1C = dword ptr -1Ch .text:1002B990 var_18 = dword ptr -18h .text:1002B990 var_14 = dword ptr -14h .text:1002B990 var_10 = dword ptr -10h .text:1002B990 var_C = dword ptr -0Ch .text:1002B990 var_8 = dword ptr -8 .text:1002B990 var_4 = dword ptr -4 .text:1002B990 arg_0 = dword ptr 4 .text:1002B990 arg_4 = dword ptr 8 .text:1002B990 arg_8 = dword ptr 0Ch .text:1002B990 arg_C = dword ptr 10h .text:1002B990 arg_10 = dword ptr 14h .text:1002B990 arg_14 = dword ptr 18h .text:1002B990 arg_18 = dword ptr 1Ch .text:1002B990 arg_1C = dword ptr 20h .text:1002B990 arg_20 = dword ptr 24h .text:1002B990 arg_24 = dword ptr 28h .text:1002B990 arg_28 = dword ptr 2Ch .text:1002B990 arg_2C = dword ptr 30h .text:1002B990 arg_30 = byte ptr 34h .text:1002B990 arg_34 = byte ptr 38h .text:1002B990 arg_38 = dword ptr 3Ch .text:1002B990 arg_3C = byte ptr 40h .text:1002B990 arg_40 = byte ptr 44h .text:1002B990 arg_44 = dword ptr 48h .text:1002B990 arg_48 = dword ptr 4Ch .text:1002B990 arg_4C = dword ptr 50h .text:1002B990 arg_60 = dword ptr 64h .text:1002B990 .text:1002B990 sub esp, 44h .text:1002B993 mov ecx, [esp+44h+arg_44] .text:1002B99A xor eax, eax .text:1002B99C mov ah, [esp+44h+arg_3C] there are some more arguments expected on the stack than only a pointer to a struct ... Link to comment Share on other sites More sharing options...
linus Posted September 24, 2010 Author Share Posted September 24, 2010 this dllstruct thing is definetly good to make a non-C(pp)-pro's head smoking But can I assume that I have really fixed my problem or do you mean the way I did is not the real one (means: one of those maybe-maybe-not solutions)? Link to comment Share on other sites More sharing options...
seandisanti Posted September 24, 2010 Share Posted September 24, 2010 this dllstruct thing is definetly good to make a non-C(pp)-pro's head smoking But can I assume that I have really fixed my problem or do you mean the way I did is not the real one (means: one of those maybe-maybe-not solutions)?looks like you've got it, I think andyg was offering advice for helping to solve the ByRef, ByVal decision when calling a dll Link to comment Share on other sites More sharing options...
linus Posted September 25, 2010 Author Share Posted September 25, 2010 ... I think andyg was offering advice for helping to solve the ByRef, ByVal decision when calling a dll... and it's a really good advice - think getting those infos via debugger will save me a lot of time with things I am currently working on. But I have to out myself as a newb to this ... I know "typical "debugging of .exe projects from within e.g. Visual Studio, but think it's different handling for a dll called from au3? A small hint just to get me in the right direction would be nice! Link to comment Share on other sites More sharing options...
AndyG Posted September 25, 2010 Share Posted September 25, 2010 (edited) but think it's different handling for a dll called from au3? no, a "call" is only a jump to an adress in the memory. The variables were usually transfered into the dll-function via the stack (which is not more than a peace of memory). The AutoIt "DllCall()"-Function is a wrapper for "push the returnadress and all variables (size is depending of the types) onto the stack and jump to the address in memory, where the Function resides. When the Function is finished, pop all parameters from the stack and jump to the (saved) returnadress, back to the calling program". In 64Bitcode there´s some diffrence, but not much So if you disassemble code (not matter which compiler created it), the way to call a "Function()" is always the same! That's what trancexx mentioned with "Dot operator in c(++) is used to access data members." think getting those infos via debugger will save me a lot of time with things I am currently working onIf you understand "how" the Processor is working with your code, it's much more easyier to debug than if you only know "that" the code works until it crashes. Edited September 25, 2010 by AndyG Link to comment Share on other sites More sharing options...
linus Posted September 25, 2010 Author Share Posted September 25, 2010 If you understand "how" the Processor is working with your code, it's much more easyier to debug than if you only know "that" the code works until it crashes.Sometimes crazy - trying to get one thing working you learn about two additional things Thanks for actually helpful info! Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now