Jump to content

Structure allocation


Recommended Posts

I'm writing wrappers for Open Dynamics Engine, which is open source solver for rigid multibody systems (BTW, anyone interested in it?). It has very clean and well documented C API (although it is written in C++) and does not require to write any additional DLL wrapper. With one exception. It uses quite unusual way to retrieve values of forces in particular constrains. For each constrain you want to retrieve force during simulation, you have to allocate defined structure (6 floats) and pass its pointer to special function before the simulation. During simulation loop values in allocated structures are updated automaticly and there is no function to read them (what for it would be if you program in C...). But how to to it with LV?

One idea I have is to create additional DLL with 3 functions: 1st allocates memory for the structure (or even for given number of bytes to make it more universal) and returns a pointer, 2nd reads from the pointer and return value (or string to be casted to whatever you want) and 3rd deallocates memory. Simple but ugly and leads to memory leaks if LV wrappers user won't care to deallocate memory. Are there any other ways to to this?

Another point, but less important. ODE provides simple but convienient functions for 3D visualisations (rather for debug purposes). But it works using callback - you have to pass a function with main simulation loop, so making any DLL wrapper for that (until it is not LV DLL) does not make sense because all LV wrappers become unusable. Anything changed with that in 8.6? I mean is it possible in any way to directly pass a strictly typed VI as callback function?

Link to comment

QUOTE (vugie @ Aug 14 2008, 04:02 AM)

I'm writing wrappers for Open Dynamics Engine, which is open source solver for rigid multibody systems (BTW, anyone interested in it?). It has very clean and well documented C API (although it is written in C++) and does not require to write any additional DLL wrapper. With one exception. It uses quite unusual way to retrieve values of forces in particular constrains. For each constrain you want to retrieve force during simulation, you have to allocate defined structure (6 floats) and pass its pointer to special function before the simulation. During simulation loop values in allocated structures are updated automaticly and there is no function to read them (what for it would be if you program in C...). But how to to it with LV?

One idea I have is to create additional DLL with 3 functions: 1st allocates memory for the structure (or even for given number of bytes to make it more universal) and returns a pointer, 2nd reads from the pointer and return value (or string to be casted to whatever you want) and 3rd deallocates memory. Simple but ugly and leads to memory leaks if LV wrappers user won't care to deallocate memory. Are there any other ways to to this?

I am not sure there's a safe way to pass a pointer to LabVIEW-allocated data and have it be continuously updated after the original function call completes. LabVIEW might think the memory is not being used anymore and deallocate it or overwrite it.

So I believe you might have to write at least one wrapper function to do a malloc for the struct type and return a pointer to the memory. After that, you won't need any additional functions to simply read the value. LabVIEW has a built-in function in LabVIEW.exe called MoveBlock. You call it much like a DLL function in the Call Library Function Node, except you type in LabVIEW instead of a DLL name. MoveBlock can copy from a source location (the malloc'd struct from the simulation) to a target location (a LabVIEW cluster with 6 doubles). See chapter 6 of this PDF for more info on the function prototype for MoveBlock. There's possibly also an appropriate function that resembles malloc that you can call directly from LabVIEW to avoid needing a wrapper DLL at all. Check out AZNewPtr for instance.

If I understand the second problem correctly, you need to get a function pointer to a VI to pass to the simulation DLL. This is rather tricky, but someone found a roundabout way to do this using LabVIEW's .NET callback functionality. Check out the solution here.

Link to comment
  • 2 weeks later...

Thank you for the answer

QUOTE (ragglefrock @ Aug 14 2008, 03:28 PM)

LabVIEW has a built-in function in LabVIEW.exe called MoveBlock. You call it much like a DLL function in the Call Library Function Node, except you type in LabVIEW instead of a DLL name. MoveBlock can copy from a source location (the malloc'd struct from the simulation) to a target location (a LabVIEW cluster with 6 doubles). See chapter 6 of this PDF for more info on the function prototype for MoveBlock. There's possibly also an appropriate function that resembles malloc that you can call directly from LabVIEW to avoid needing a wrapper DLL at all. Check out AZNewPtr for instance.

I didn't play arount much with these functions, but such solution seems to work. But how it will look like with built application running with runtime engine only?

QUOTE

If I understand the second problem correctly, you need to get a function pointer to a VI to pass to the simulation DLL. This is rather tricky, but someone found a roundabout way to do this using LabVIEW's .NET callback functionality. Check out the solution
.

I knew this article and I tried to reproduce this functionality some time ago but without success (I had problems with compiler as I'm totally not familiar with NET environment). However, I wasn't strongly determined to do that...

I have another issue around this subject:

ODE is designed to let to compile it either for single or double precision computations. It simply uses some macros to set input parameters for ALL (400+) functions to float or double. I would like to reproduce such design in my wrappers. All type definitions I use I built using abstract type Real which holds now Single type. So changing this type to Double obviously updates all other types. But for CEF Node I have to uniquly determine numeric input type. As most parameters are passed as values I can't use Adapt to Type which passes only pointers. Have I to use Conditional Disable Structure? I discovered some time ago that extensive use of disable structures decreases performace. And beside that when I wire to certain function parameter from my Real type I get coercion dot even when parameter type and type inside Real agrees. I understand why it appears, but will it influence on performance? What approach should I choose to be able to be able to bulid my library for either single or double precision?

Another point. Most functions in ODE as first argument uses ID of something (world, body, joint, etc.) it operates on. It's simply a pointer to proper structure. I currently use UInt32 to handle it. But what if the DLL will be compiled for 64-bit architecture? Maybe should I use Int64 from the start? Will then 32-bit DLL behave properly?

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.