Link to home
Start Free TrialLog in
Avatar of Tom_P
Tom_P

asked on

std::map and DLL functions

When using std::map as an argument passed to a dll, I always get an access violation. I've now resorted to the simplest of programs, but still can't work it out... Here's a snippet:

/* ========= .dll file =============== */
#include <map>
#include <string>

using namespace std;

typedef map< int, int > Map;

extern "C" __declspec( dllexport ) void Test( Map & m )
{
//keep getting access violations as soon as I try to use m
     int i = m[1];
     int j = m[2];
}
/* ======== .exe file =================== */
The .exe file is a very simple main() which calls Test() with a map it creates. I get the access violation whether I link dynamically using "LoadLibrary()" or statically by linking with the .lib.

Any comments will be greatly appreciated.
Tom

Avatar of lidorc
lidorc

You pass a reference to a C function..
Pass a pointer instead
In other words:
not

extern "C" __declspec( dllexport ) void Test( Map & m )

but

extern "C" __declspec( dllexport ) void Test( Map * m )
Avatar of Tom_P

ASKER

lidorc,

thanks for the interest but I think you will find that 'extern "C" ' is just a linkage convention. It tells the compiler to use the "C" name mangling, as oposed to the "C++" style.

Tom
Avatar of jkr
Try to set the CRT to be used as "multithreaded DLL" for both projects ( DLL&EXE) under "Project Settings | C++ | Code Generation | Use Runtime Library..."
ASKER CERTIFIED SOLUTION
Avatar of thienpnguyen
thienpnguyen

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
If it can help:
I had the same problem... Simply put (very simply put), with no specific settings or changes as proposed in the previous comment, I think it's because map have entity (dll/exe) specific "end" iterator. So if you pass a map (or list, multimap, any such container but a vector) from a dll to an exe (or another dll), the latter won't be able to recognize the end of the sequence, therefor causing the access violation.

The vector is ok because it's a sequential memory container (not node based). It can be used as pointer params (type*).

A simple way to bypass this is to convert the map to a vector of pair, pass the vector from a dll to another, and reconvert the vector to a map. Of course there is a lot of overhead, but it's better than a crash! :) Or only use vector, if possible!
Another solution is the exports proposed in the previous comment (I briefly tried, but got confused and bailed out...).

In MS visual studio 7 (.net) they should have a new implemation of STL that will not have this anoying limitation... but I have not had the chance to use it yet...

Hope this will help.

A>
Avatar of Tom_P

ASKER

Thanks very much everyone for your interest. The problem is now resolved.
Tom
Tom:
I have encountered  a same problem, my function define is:


extern "C" __declspec( dllexport ) void Test( vector<int> & m )
{
    m.push_back(10);
}

I try to get the vector in my executable program.
in
http://beta.experts-exchange.com/questions/20253705/Import-a-template-class-from-DLL.html


-- Dan said

"
The only STL container that can currently be exported is vector.
"

-- Dan

Thanks very much everyone for your interest. The problem is now resolved.
Tom
Tom please tell me how you resolved your problem.
thank you!