Diese Seite mit anderen teilen ...

Informationen zum Thema:
Forum:
WinDev Forum
Beiträge im Thema:
11
Erster Beitrag:
vor 4 Jahren, 11 Monaten
Letzter Beitrag:
vor 4 Jahren, 11 Monaten
Beteiligte Autoren:
Tobi_from_HH, Peter Holemans, X4S

Using C++ DLL with double-type parameter

Startbeitrag von Tobi_from_HH am 22.08.2013 07:42

Hey all.

I tyring to use a simple C++ DLL which add two values and returns the result. Here is the function:

int Add( int num1, int num2) { return num1+num2; }

This functions works when I call it from WinDev. Here is the code:
Result1 is a int;
Number1 is int = 1;
Number2 is int = 2;
Result1 = CallDLL32("MathFuncsDll.dll", "Add",Number1, Number2);

Now I want change the c++ datatype int to float or double. But then it don't work. I tryed diffrent datatypes in WinDev such real, 4-byte real, numeric.

Have anyone a idea for me?

Thank you. Tobi

Antworten:

Hi Tobi,

To C(++) DLL calls you often need to pass values by reference. That is the memory pointer. If we are talking about a 32-bit dll then typically you need to declare your variables as real on 4 bytes (=32 bits).

Next you pass the variables by memory pointer:
Result1 is a real on 4 bytes
Number1 is real on 4 bytes = 1
Number2 is real on 4 bytes = 2
Result1 = API("MathFuncsDll.dll", "Add",&Number1, &Number2)
//Mind the ampersands to pass by reference...

Cheers,

Peter H.

von Peter Holemans - am 22.08.2013 07:51
Hi Peter,

Yes it's a 32-bit dll. I tried to pass the values by reference but it still don't work. My C++ code:

float Add( float *num1, float *num2) { return (*num1 + *num2); }

In WinDev I used the code from your post.

Any idea whats wrong?

von Tobi_from_HH - am 22.08.2013 08:30
Hi Tobi,

Many questions:
Did you build the DLL yourself?
Are the functions within the DLL exported (meaning they can be accesses from outside)?
What are your build options in (V)C++?
Did you do a LoadDLL() before trying the CallDDLL32() and then an UnloadDLL()?
Was there an error at executing LoadDLL()?
...

Cheers,

Peter H.

von Peter Holemans - am 22.08.2013 09:18
Yes I built the DLL self with Visual Studio 2010. The functions are exported. I checked the DLL with another C++ programm. The DLL works with WinDev as long as I used integer parameter.

Now I tried to pass the result as a parameter like the numbers. And this works! So I think the returning parameter is the problem.

Is it possible in WinDev to declare a pointer? Like

Result1 is real pointer;
...
Result1 = CallDLL32("MathFuncsDll.dll", "Add",Number1, Number2);
// The function 'Add' returns a floating pointer to the result.

von Tobi_from_HH - am 22.08.2013 10:51
Hi Tobi,

The function probably only returns the address pointer so:
Result1 is real on 4 bytes
&Result1 = CallDLL32("MathFuncsDll.dll", "Add",Number1, Number2)
Trace(Result1)

Cheers,

Peter H.

PS Aside from that: Why would you like to use an external math library if W-Language has tons of them?
Mathematical_functions
Financial Functions
Functions for managing matrixes
Satistical functions

von Peter Holemans - am 22.08.2013 11:48
Hi Peter,

the function "add" returns a address pointer. so I need a pointer in WinDev. Your code:

Result1 is real on 4 bytes
&Result1 = CallDLL32("MathFuncsDll.dll", "Add",Number1, Number2)

produce a syntax error. Is there something like: float *result_prt ?

Tobi

von Tobi_from_HH - am 22.08.2013 12:21
Hi Tobi,

Sorry... RunDLL32 or API expects an integer back (See CallDLL32)

This integer is a memory address in your case I guess...
So it will be something like (Haven't tested though):

ResultAddr is int on 4 bytes
ResultFloat is real
ResultAddr = CallDLL32("MathFuncsDll.dll", "Add",Number1, Number2)
If ResultAddr > 0 then
trace(ResultAddr)
trace(&ResultAddr)
Transfer(&ResultFloat,ResultAddr,4)
end


Not tested though...

Cheers,

Peter H.

von Peter Holemans - am 22.08.2013 13:22
Why I need a external math library? I simply needed a simple example for testing ;)

So. I tested your idea and it works! Thanks for your help.

Below my code for other users with the same problem:
c++ code:
float *Add(float *num1, float *num2)
{
// define as static or global !
static float result = (*a + *b);
return &result;
}

W-Language code:
resultFloat is real on 4 bytes;
resultAddr is int on 4 bytes;
n1 is real on 4 bytes = Number1;
n2 is real on 4 bytes = Number2;

// call add function from the MathFuncsDll.dll
resultAddr = CallDLL32("MathFuncsDll.dll", "Add",&n1, &n2);
IF resultAddr > 0 THEN
Transfer(&resultFloat,resultAddr,4);
Result1 = resultFloat;
ELSE
Error("Add");
END

von Tobi_from_HH - am 22.08.2013 14:55
Hi Tobi,

Glad it worked out!
Looking at your code: One of the things you can skip in WX is semi-colon'ing your code lines. W-Language doesn't need that, only if you want several statements on one line of code.

It's cleaner without them...

Cheers,

Peter H.

von Peter Holemans - am 22.08.2013 15:10
Hi Tobi,

why not use the MS-way? Then you can pass also char * for returning text and you don't need to call an extra Transfer(). The result is an int, e.g. 0, 1, errorcode, number of CRLF in the text, and so on.

Regards,
Xavier


int Add(float *num1, float *num2,float *result)
{

*result = (*a + *b);
return 1;
}


W-Language code:
resultFloat is real on 4 bytes
n1 is real on 4 bytes = Number1
n2 is real on 4 bytes = Number2
result is int

// call add function from the MathFuncsDll.dll
result = CallDLL32("MathFuncsDll.dll", "Add",&n1, &n2,&resultFloat);

von X4S - am 23.08.2013 11:10
Zur Information:
MySnip.de hat keinen Einfluss auf die Inhalte der Beiträge. Bitte kontaktieren Sie den Administrator des Forums bei Problemen oder Löschforderungen über die Kontaktseite.
Falls die Kontaktaufnahme mit dem Administrator des Forums fehlschlägt, kontaktieren Sie uns bitte über die in unserem Impressum angegebenen Daten.