How do you send a 'float' to a DLL?

● ARCHIVED · READ-ONLY
Started by DivideByZero 14 posts View original ↗
  1. Hi Guys,

    I have my own DLL happily talking with RPG Maker VX Ace, but can't figure out how to send a 'float' and an input parameter.

    As far as I can see the following data types are allowed as input;

    # P - String
    # I - Integer
    # L - Long
    # V - Void

    So as a result, I am unable to get my DLL to receive the correct floating point value.

    I could convert the float to a string and send it that way, but that would be clunky and slow.

    Any advice would be greatly appreciated :)
  2. that depends on the functions inside the dll. Those functions need to be defined in a way to accept the data you want them to receive.

    so if you want to help you need to show us the functions you programmed inside the dll.
    and if that dll wasn't programmed by you but by someone else (and then hopefully not using illegal data), then you need to link us to the source of the dll.
  3. Well take something as simple as this;

    Code:
    #define fn_export extern "C" __declspec (dllexport)
    
    fn_export float ReturnSomeFloat()
    {
          return 1.23456f;
    }

    With the data types of P, I, L, and V. It can't be done.

    The only way I can think of how to do it is to have some pre-determined decimal point depth (say accuracy to 3 DP's), multiply it by 1000, send an integer then divide it by 1000 at the other side.
  4. I have tried every letter in the alphabet. It seems that RPG Maker is not capable of sending or receiving a decimal value to/from a DLL.

    Very frustrating (and surprising) indeed. :|
  5. I'm not exactly sure how this works, but isn't possible to use void and covert it to a float when receiving or sending?
  6. TakeHomeTheCup said:
    I'm not exactly sure how this works, but isn't possible to use void and covert it to a float when receiving or sending?

    In RPG Maker's environment a 'V'oid is just a placeholder for no argument or return value.

    So in effect it can only handle integers, strings, or nothing.
  7. I'm not familiar with dll, but can you use string that convert to float back and forth?
    The argument is float, but converted into string first, pass to dll.
    In dll, the string converted into float for whatever reason, then pass back as a string to RM.

    Edit: I didn't read, you already tried that way, but it isn't that it will drop your fps anyway, or it will?
  8. TheoAllen said:
    I'm not familiar with dll, but can you use string that convert to float back and forth?
    The argument is float, but converted into string first, pass to dll.
    In dll, the string converted into float for whatever reason, then pass back as a string to RM.

    Edit: I didn't read, you already tried that way, but it isn't that it will drop your fps anyway, or it will?

    Yeah, there are hacks to get around it. Most efficient way would be send an integer and divide by a predetermined value at either side. A string would be pretty inefficient.

    Just found it odd that RPG Maker can't handle such a fundamental data type.


    [edit]
    This is a workaround I have created (adding two floating point values, as an example). Far from ideal but at least I can progress with what I am creating.

    Code:
    std::string conversion;
    
    fn_export const char* add(char* val0, char* val1)
    {
        double value0 = atof(val0);
        double value1 = atof(val1);
        double result = value0 + value1;
    
        std::ostringstream ss;
        ss << std::setprecision(10);
        ss << result;
        conversion = ss.str();
    
        const char* finalString = conversion.c_str();
        return finalString;
    }

    You also have to do conversions on the input and output to have the program make use of the values.

    Soooo much overhead for such a seemingly simple task. :(
  9. Have you tried passing the float as a pointer?
    I recommend you download the source code for a Ruby 1.9.3 release and check out how the Float is stored internally.
    Try and see if it works should use require the same data type as the argument

    Edit:
    Do actual performance tests to see if the overhead actually matters or not.
    It is possible the Win32API call overhead makes the little extra work you require insignificant.
  10. Zeriab said:
    I recommend you download the source code for a Ruby 1.9.3 release and check out how the Float is stored internally.

    Interesting...

    So this is actually a Ruby thing and not RPG Maker?

    Sorry, being 100% new to both Ruby and RPG Maker I don't yet know where the syntax crosses over. But now knowing this, it gives more avenues for finding the best solution.
  11. I asked the same question on the Ruby forums on Monday and not a single reply.

    Funnily enough there has only been three topics posted since that day which leads me to believe that the Ruby language has been deceased for many years.
  12. Ugggh! The guys on the Ruby forums don't know either. I'll can the idea.
  13. Just going to share what I do:
    DLL
    Code:
    extern "C" __declspec (dllexport) void method(float * var)
    {
        var[0] = 2.0 * var[0];
    }
    Ruby
    Code:
    myDLL = Win32API.new('dll','method','p','')
    var = [1.0]
    result = myDLL.call(var.pack("F*"))
    
    print result.unpack("F*")[0] #should be 2.0
  14. Cool thanks! I'll give that method a try.