Wrong DLL output
-
Cedric Moonen wrote:
...but shouldn't you pass the integer ByVal instead of ByRef ?
I don't see this making any difference since the
ByVal
/ByRef
keyword only affect how the argument is sent torndNum()
, not what type of value is returned from it."Love people and use things, not love things and use people." - Unknown
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
I don't know how it is implemented in VB, but if the ByRef is in fact passing the address of the variable, then this is the problem because that will have an impact on what the function returns (because the random number will be between 0 and that number).
Cédric Moonen Software developer
Charting control [v1.3] -
Quoted from this page[^]: One important note is that all parameters must be passed with the ByVal keyword. This is because Visual Basic always passes parameters ByRef by default. Since C/C++ usually passes by value, this must be specified in the Visual Basic declaration. This is all that is necessary when standard C variable types (int, long, etc.) are used, however complex data types like strings and arrays require more overhead on both the client and DLL sides. They also specify that a VB integer correspond to a short in C/C++. So, change the C function to accept a short and check if it works (and don't forget the ByVal).
Cédric Moonen Software developer
Charting control [v1.3]Hi first of all thanks for quick reply. :) Some how I realised that the speed of DLL and EXE could vary, so now I have timer which will get number every second. AND I did what you just said and now it's giving me random number between 0(1) - 100 (never seen 0 or 100) but yeh. But what happens now is that the numbers comes in ascending order.
2
12
43
56
78
90
95
1
3
5
and so on...What surprises me most is that the same code works perfect with C but not with VB. :confused:
- Stop thinking in terms of limitations and start thinking in terms of possibilities -
-
also, try using "Long" instead of "Integer" for the VB declaration. an Integer is 16 bits, a Long is 32 bits (like a C int)
-
killerp wrote:
...I'm trying to receive RANDOM number from C and add to my VB form.
Unless this is just a test to see if the two can communicate, or you are just wanting to see how a DLL works, why not just let your VB app generate its own random numbers?
killerp wrote:
But the number received is not random...
How are you verifying this?
killerp wrote:
But the number received is...way to big than what I pass into the parameter.
This statement makes little sense. The argument passed to
rndNum()
is simply used to seed the random number generator. It has no bearing on anything else."Love people and use things, not love things and use people." - Unknown
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
Hi, Thanks for reply. I haven't got any special method to verify the numbers received... It's just common sense to recognise Random numbers. The other thing I figured out just now is that the problem lies in
srand( (unsigned)time( NULL ) );
I just removed this line and everything is working as I expected! But now i will get same numbers every time I use it. This simple dll is becoming more and more complicated...- Stop thinking in terms of limitations and start thinking in terms of possibilities -
-
Hi, Thanks for reply. I haven't got any special method to verify the numbers received... It's just common sense to recognise Random numbers. The other thing I figured out just now is that the problem lies in
srand( (unsigned)time( NULL ) );
I just removed this line and everything is working as I expected! But now i will get same numbers every time I use it. This simple dll is becoming more and more complicated...- Stop thinking in terms of limitations and start thinking in terms of possibilities -
You should call srand only once, for example in the DllMain.
Cédric Moonen Software developer
Charting control [v1.3] -
Hi, I have a DLL written in C and I am calling it from VB and I am using Visual Studio 6. The problem I have is that I'm trying to receive RANDOM number from C and add to my VB form. But the number received is not random or is way to big than what I pass into the parameter. Here's the Code for .CPP
#include "stdafx.h" #include #include #include BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; } int _stdcall rndNum(int iMaxNum) { int iNum; //srand( (unsigned)iMaxNum ); srand( (unsigned)time( NULL ) ); iNum = rand() % iMaxNum; return iNum; }
.DEF fileLIBRARY CdllRndNum EXPORTS rndNum @1
VB CodePrivate Declare Function rndNum Lib "F:\Year - 2\CdllRndNum\Debug\CdllRndNum.dll" (ByRef iMaxNum As Integer) As Integer Sub AddNums() Dim i As Integer For i = 0 To 40 List1.AddItem rndNum(100) Next i End Sub
Result VB:28156
28156
28156
28156
28156 and same and same again....Result C:
Number is 30
Number is 43
Number is 16
Number is 24
Number is 25
Number is 63
Number is 62
Number is 84
Number is 40
Number is 64
Number is 77
Number is 79
Press any key to continueThe C code gives me perfect results in C Console app. But not in VB. Anyone any idea what is going wrong??:confused::confused::confused:
- Stop thinking in terms of limitations and start thinking in terms of possibilities -
1. You need to use the following declaration
Private Declare Function rndNum Lib "F:\Year - 2\CdllRndNum\Debug\CdllRndNum.dll" (ByVal iMaxNum As Long) As Long
killerp wrote:
srand( (unsigned)time( NULL ) );
2. The above is a mistake. Don't initialise the random number generator each time you're calling it (and remember,
time
returns seconds). :)If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke -
You should call srand only once, for example in the DllMain.
Cédric Moonen Software developer
Charting control [v1.3]Yeh, I got this sorted now. It was srand. Because the speed of accessing values and passing value is so fast it was passing same time into srand. SO now i got static int and it will make sure that srand only takes place once when the application is started. Anyway thanks for all you guys support. THANK YOU ALL.
- Stop thinking in terms of limitations and start thinking in terms of possibilities -
-
You should call srand only once, for example in the DllMain.
Cédric Moonen Software developer
Charting control [v1.3]Probably will be better exporting
srand
too, otherwise he needs to restart the executable each time he needs a different sequence. :)If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke -
Hi, Thanks for reply. I haven't got any special method to verify the numbers received... It's just common sense to recognise Random numbers. The other thing I figured out just now is that the problem lies in
srand( (unsigned)time( NULL ) );
I just removed this line and everything is working as I expected! But now i will get same numbers every time I use it. This simple dll is becoming more and more complicated...- Stop thinking in terms of limitations and start thinking in terms of possibilities -
In order for what you have to work, you're going to need a really, really slow computer. The problem is not
int
vs.long
vs.short
, orByVal
vsByRef
, but rather thatrndNum()
is being called so fast, that each call tosrand()
is seeding with the same value. To demonstrate this, put a call toSleep(750)
betweensrand()
andrand()
. Movingsrand()
toDllMain()
is what you need."Love people and use things, not love things and use people." - Unknown
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
-
Hi, I have a DLL written in C and I am calling it from VB and I am using Visual Studio 6. The problem I have is that I'm trying to receive RANDOM number from C and add to my VB form. But the number received is not random or is way to big than what I pass into the parameter. Here's the Code for .CPP
#include "stdafx.h" #include #include #include BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; } int _stdcall rndNum(int iMaxNum) { int iNum; //srand( (unsigned)iMaxNum ); srand( (unsigned)time( NULL ) ); iNum = rand() % iMaxNum; return iNum; }
.DEF fileLIBRARY CdllRndNum EXPORTS rndNum @1
VB CodePrivate Declare Function rndNum Lib "F:\Year - 2\CdllRndNum\Debug\CdllRndNum.dll" (ByRef iMaxNum As Integer) As Integer Sub AddNums() Dim i As Integer For i = 0 To 40 List1.AddItem rndNum(100) Next i End Sub
Result VB:28156
28156
28156
28156
28156 and same and same again....Result C:
Number is 30
Number is 43
Number is 16
Number is 24
Number is 25
Number is 63
Number is 62
Number is 84
Number is 40
Number is 64
Number is 77
Number is 79
Press any key to continueThe C code gives me perfect results in C Console app. But not in VB. Anyone any idea what is going wrong??:confused::confused::confused:
- Stop thinking in terms of limitations and start thinking in terms of possibilities -
-
i may not be an expert but if all you need is a random number in VB you should use:
' Initialize the random-number generator. Randomize() ' Generate random value between 1 and 6. Dim value As Integer = CInt(Int((6 * Rnd()) + 1))
Hey Thanks for Reply, but I have already mentioned that I DO NOT WANT TO USE VB (and yes I do know how to do it in VB. For .NET there is another method available by using Random class and then Random.Next()) But anyway thanks for reply. :)
- Stop thinking in terms of limitations and start thinking in terms of possibilities -