views:

469

answers:

5

I'm trying to explicitly link with a DLL. No other resources is available except the DLL file itself and some documentation about the classes and its member functions.

From the documentation, each class comes with its own

  1. member typedef
    example: typedef std::map<std::string,std::string> Server::KeyValueMap, typedef std::vector<std::string> Server::String Array
  2. member enumeration
    example: enum Server::Role {NONE,HIGH,LOW}
  3. member function
    example: void Server::connect(const StringArray,const KeyValueMap), void Server::disconnect()

Implementing the codes from google search, i manage to load the dll can call the disconnect function..

dir.h

LPCSTR disconnect = "_Java_mas_com_oa_rollings_as_apiJNI_Server_1disconnect@20";  
LPCSTR connect =   
"_Java_mas_com_oa_rollings_as_apiJNI_Server_1connect@20";

I got the function name above from depends.exe. Is this what is called decorated/mangled function names in C++?

main.cpp

#include <iostream>
#include <windows.h>
#include <tchar.h>
#include "dir.h"

typedef void (*pdisconnect)();

int main()
{
    HMODULE DLL = LoadLibrary(_T("server.dll"));  
    pdisconnect _pdisconnect;`

    if(DLL)
    {
     std::cout<< "DLL loaded!" << std::endl;
     _disconnect = (pdisconnect)GetProcAddress(DLL,disconnect);


     if(_disconnect)
     {
      std::cout << "Successful link to function in DLL!" << std::endl;
     }

     else
     {
      std::cout<< "Unable to link to function in DLL!" << std::endl;
     }
    }  
    else   
{  
std::cout<< "DLL failed to load!" << std::endl;  
}  
FreeLibrary (DLL);  
return 0;}

How do i call (for example) the connect member function which has the parameter datatype declared in the dll itself?

+2  A: 

Unless you use a disassembler and try to figure out the paramater types from assemly code, you can't. These kind of information is not stored in the DLL but in a header file coming with the DLL. If you don't have it, the DLL is propably not meant to be used by you.

Frank Bollack
A: 

I would be very careful if I were you: the STL library was not designed to be used across compilation boundaries like that.

Not that it cannot be done, but you need to know what you are getting into.

This means that using STL classes across DLL boundaries can safely work only if you compile your EXE with the same exact compiler and version, and the same settings (especially DEBUG vs. RELEASE) as the original DLL. And I do mean "exact" match.

The C++ standard STL library is a specification of behavior, not implementation. Different compilers and even different revisions of the same compiler can, and will, differ on the code and data implementations. When your library returns you an std::map, it's giving you back the bits that work with the DLL's version of the STL, not necessarily the STL code compiled in your EXE.

(and I'm not even touching on the fact that name mangling can also differ from compiler to compiler)

Without more details on your circumstances, I can't be sure; but this can be a can of worms.

Euro Micelli
thanks for your reply... What other details do you need?.. I'm not sure what i details i should be looking for..
justin
Well -- essentially -- where did the DLL come from. I would be very concerned if you said it was a DLL handed down to you and you didn't know where it came from, or what compiler was used. I would be much less concerned if it had been developed by someone else in your organization and you knew exactly what compiler they were using and you could coordinated your compiler upgrades with the other person. Just as @fnieto, I didn't notice the Java Native Interface connection; I have no experience with JNI.
Euro Micelli
A: 

more info:

  • The DLL comes with an example implementation using Java. The Java example contains a Java wrapper generated using SWIG and a source code.
  • The documentation lists all the class, their member functions and also their datatypes. According to the doc, the list was generated from the C++ source codes.(??)
  • No other info was given (no info on what compiler was used to generate the DLL)

My colleague is implementing the interface using Java based on the Java example given, while I was asked to implement using C++. The DLL is from a third party company.

I'll ask them about the compiler. Any other info that i should get from them?

I had a quick read through about JNI but i dont understand how it's implemented in this case.

justin
A: 

i'm a little confused... (ok, ok... very confused)

  1. Do i call(GetProcAddress) each public member function separately only when i want to use them?
  2. Do i create a dummy class that imitates the class in the dll. Then inside the class definition, i call the equivalent function from the DLL? (Am i making sense here?) fnieto, is this what you're showing me at the end of your post?
  3. Is it possible to instantiate the whole class from the DLL?

I was trying to use the connect function described in my first post. From the Depends.exe DLL output,

  • std::map // KeyValueMap has the following member functions: *del, empty, get, has_1key,set*
  • std::vector // StringArray has the following member functions: add, capacity, clear, get, isEMPTY, reserve, set, size

which is different from the member functions of map and vector in my compiler (VS 2005)...

Any idea? or am i getting the wrong picture here...

justin
This link: http://www.codeguru.com/cpp/w-p/dll/importexportissues/article.php/c123 was the only thing worth in the post you refer to.
fnieto
A: 

I would reformulate the question as:

How to use a JNI dll from C++

fnieto
would it be better to create a new question or just change the title of this question?
justin
think i'll just post a new question.... thanks guys for all the great comments and advice... really appreciate it..
justin