-
rand functions in a DLL
I am trying to use the srand and rand functions in a DLL, but for some reason I keep getting access violations (and this function worked before it was part of a DLL).
Here's a short example of my problem:
Code:
//this is the DLL
#include <windows.h>
#include <ctime>
extern "C"
{
__declspec(dllexport) int Foo(char* str)
{
int len = strlen(str);
//if I change the following three lines to this:
//str[5] = '^';
//everything works
srand(time(0));
int num = rand()%len;
str[num] = '^';
return 0;
}
}
Code:
#include <windows.h>
#include <iostream>
typedef int (*MYDLLPROC)(char*);
MYDLLPROC Foo;
int main()
{
char str[] = "Hello World!";
HMODULE hDLL = LoadLibrary("dllClassTest.dll");
Foo = (MYDLLPROC)GetProcAddress(hDLL,"Foo");
Foo(str); //access violation
std::cout<<str;
}
I'm using VS.NET 2003 if that makes a difference.
-
Two suggestions:
1. Do error checking. I suspect LoadLibrary() failed to find the dll
2. Copy the dll into the main project's source directory or into a directory that is in your PATH environment variable.
3. It works when compiled with Dev-C++ and the dll is in the test programs's source directory.
Code:
int main()
{
char str[] = "Hello World!";
HMODULE hDLL = LoadLibrary("dllClassTest.dll");
if( hDLL == 0)
{
std::cout << "LoadLibrary error" << std::endl;
std::cin.ignore();
return 1;
}
Foo = (MYDLLPROC)GetProcAddress(hDLL,"Foo");
if( Foo == 0)
{
std::cout << "GetProcAddress error" << std::endl;
std::cin.ignore();
return 1;
}
Foo(str); //access violation
std::cout<<str;
std::cin.ignore();
}
-
No, I'm sure LoadLibrary is successful for two reasons. First, other functions in the DLL work correctly. Second, if remove any lines from the test DLL that I posted, the function works correctly without any errors.
If it works with Dev-C++ it sounds like an VS problem or possibly something wrong with my project settings (but I'm not sure what I should change...)
Edit: And in my actual project I do error checking, just so you know ;)
-
I just discovered a way I can get it to work, but it causes other problems. In my linker options I have:
Force Symbol References: __DllMainCRTStartup@12
Resource Only DLL: Yes (/NOENTRY)
If I remove the first, and select no for the second, the program works if I'm not debugging it. However, I had those two lines because if I try to debug without them, I receive an unhandled exception. So, damned if I do, damned if I don't?
-
The problem might be VC++ 2003/2005 specific, I know Microsoft made a lot of major changes in that compiler. I'm in the process of porting from VC++ 6.0 to 2005 and the port is not very nice. A lot of MFC classes are now templates! and don't work well in DLLs. I don't know if your problem is similar.
-
-
Calling srand(time(0)) every time you want a new rand() can't be good.
Remember, time() is a constant (more or less) in short-lived programs.
-
>>Could it be a mismatch between the standard library being used by the DLL and the EXE?
Yup, I needed to use the /MD option. Now it works :D