By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,434 Members | 1,632 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,434 IT Pros & Developers. It's quick & easy.

C++ dllexport/dllimport

P: 8
Am doing a JNI wrap on a C++ API, am using VC7 and Eclipse. In preparation, I created a C++ executable which mimicked the flow of the JNI, i.e. a driver file which called methods in file with methods which call the API functions I want to use. That compiled and ran well. The C++ code is as follows:
My header file
Expand|Select|Wrap|Line Numbers
  1. void createSummarizer(char* rdir, char* lFile, char* key);
  2. void createInputOptions(const char* genre, const char* variant, const char* lang, const char* encoding, const char* format);
  3. void setSentenceOutput(unsigned int sentences_wanted, bool sentence_offset_only, bool normalize_score);
  4. void setPhraseOutput(unsigned int phrases_wanted, bool phrase_offset_only);
  5. void getSummary(const char* fileName);
The implementation
Expand|Select|Wrap|Line Numbers
  1. #include "inxight-summarizer.h"
  2. #include "inxight-charptr.h"
  3. #include "inxight-text.h"
  4. #include "inxight-bstream.h"
  5. #include "inxight-unicode.h"
  6. #include "inxight-unicode-utils.h"
  7. #include <iostream>
  8. #include <sys/timeb.h>  // for ftime
  9. #include <assert.h>
  10.  
  11. using namespace inxight;
  12.  
  13. static summarizer* summarzr;
  14. static summarization_input_options* inopt; 
  15. static summarization_sentence_output* sentOutput;
  16. static summarization_phrase_output* phraseOutput;
  17.  
  18. void createSummarizer(char* rdir, char* lFile, char* key)
  19. {
  20.     summarzr = new summarizer(rdir, lFile, key);
  21. }
  22.  
  23. void createInputOptions(const char* genre, const char* variant, const char* lang, const char* encoding, const char* format)
  24. {
  25.     inopt = new summarization_input_options(genre, variant, lang, encoding, format);
  26. }
  27.  
  28. void setSentenceOutput(unsigned int sentences_wanted, bool sentence_offset_only, bool normalize_score)
  29. {
  30.     sentOutput = new summarization_sentence_output(sentences_wanted, sentence_offset_only, normalize_score);
  31. }
  32.  
  33. void setPhraseOutput(unsigned int phrases_wanted, bool phrase_offset_only)
  34. {
  35.     phraseOutput = new summarization_phrase_output(phrases_wanted, phrase_offset_only);
  36. }
  37.  
  38. void getSummary(const char* fileName)
  39. {
  40.     file_byte_stream* fs = new file_byte_stream(fileName);
  41.     assert(fs);
  42.     assert(summarzr);
  43.     assert(inopt);
  44.     assert(sentOutput);
  45.     assert(phraseOutput);
  46.     summarization* summary;
  47.     summary = new summarization(*summarzr, *fs, *inopt, *sentOutput, *phraseOutput);
  48.     sequence<key_item>::const_iterator it = summary->first_key_sentence();
  49.     int count = 0;
  50.     for (;it != summary->end_key_sentence(); ++it, ++count) {
  51.         const inxight::text line = it->item_text();
  52.         printf("Sentence %i% \n", count);
  53.         printf("[len %i%, %i% \n", line.length(), it->get_score());
  54.         for(unsigned int i=0; i<line.length(); i++) {
  55.             printf("%c%", line[i]);
  56.         }
  57.         printf("%s%","\n");
  58.     }
  59.     printf(" There are %i key phrases: ", summary->number_of_key_phrases());
  60.     sequence<key_item>::const_iterator itr = summary->first_key_phrase();
  61.     for (;itr != summary->end_key_phrase(); ++itr) {
  62.         printf("%s%", itr->item_text());
  63.     }
  64. }
The driver file
Expand|Select|Wrap|Line Numbers
  1. #include "test.h"
  2.  
  3.  
  4.  
  5. void main()
  6. {
  7.     char* rdir = "../lang";
  8.     char* lFile = "../lang/license.dat";
  9.     char* key = "705553544e1a694a5f59535b561a754a5f485b4e535554491a795557575b545e1a127069757913";
  10.     const char* genre = "std";
  11.     const char* variant = "std";
  12.     const char* lang = "english";
  13.     const char* encoding = "cp_1252";
  14.     const char* format = "html";
  15.     unsigned int sentences_wanted = 5;
  16.     bool sentence_offset_only = false;
  17.     bool normalize_score = false;
  18.     unsigned int phrases_wanted = 0;
  19.     bool phrase_offset_only = false;
  20.     const char* fileName = "aaawgqM4Ob.html";
  21.  
  22.     createSummarizer(rdir, lFile, key);
  23.     createInputOptions(genre, variant, lang, encoding, format);
  24.     setSentenceOutput(sentences_wanted, sentence_offset_only, normalize_score);
  25.     setPhraseOutput(phrases_wanted, phrase_offset_only);
  26.     getSummary(fileName);
  27. }
Then I put together the JNi implementation
header file
Expand|Select|Wrap|Line Numbers
  1. /* DO NOT EDIT THIS FILE - it is machine generated */
  2.     Expand|Select|Wrap|Line Numbers
  •  
  •     
  •  
  • #include <jni.h>
  • /* Header for class com_sra_pipeline_servers_summarizer_JSummarizer */
  •  
  • #ifndef _Included_com_sra_pipeline_servers_summarizer_JSummarizer
  • #define _Included_com_sra_pipeline_servers_summarizer_JSummarizer
  • #ifdef __cplusplus
  • extern "C" {
  • #endif
  • /* Inaccessible static: resource */
  • /* Inaccessible static: license */
  • /* Inaccessible static: comp_key */
  • /* Inaccessible static: genre */
  • /* Inaccessible static: variant */
  • /* Inaccessible static: language */
  • /* Inaccessible static: numSentences */
  • /* Inaccessible static: offset */
  • /* Inaccessible static: nScore */
  • /* Inaccessible static: phraseCnt */
  • /* Inaccessible static: phraseOffset */
  • /*
  •  * Class:     com_sra_pipeline_servers_summarizer_JSummarizer
  •  * Method:    createSummarizer
  •  * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
  •  */
  • JNIEXPORT jint JNICALL Java_com_sra_pipeline_servers_summarizer_JSummarizer_createSummarizer
  •   (JNIEnv *, jobject, jstring, jstring, jstring);
  •  
  • /*
  •  * Class:     com_sra_pipeline_servers_summarizer_JSummarizer
  •  * Method:    setInOptions
  •  * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
  •  */
  • JNIEXPORT jint JNICALL Java_com_sra_pipeline_servers_summarizer_JSummarizer_setInOptions
  •   (JNIEnv *, jobject, jstring, jstring, jstring);
  •  
  • /*
  •  * Class:     com_sra_pipeline_servers_summarizer_JSummarizer
  •  * Method:    setSentenceNum
  •  * Signature: (IZZ)I
  •  */
  • JNIEXPORT jint JNICALL Java_com_sra_pipeline_servers_summarizer_JSummarizer_setSentenceNum
  •   (JNIEnv *, jobject, jint, jboolean, jboolean);
  •  
  • /*
  •  * Class:     com_sra_pipeline_servers_summarizer_JSummarizer
  •  * Method:    setPhraseOpts
  •  * Signature: (IZ)I
  •  */
  • JNIEXPORT jint JNICALL Java_com_sra_pipeline_servers_summarizer_JSummarizer_setPhraseOpts
  •   (JNIEnv *, jobject, jint, jboolean);
  •  
  • /*
  •  * Class:     com_sra_pipeline_servers_summarizer_JSummarizer
  •  * Method:    getSummary
  •  * Signature: (Ljava/lang/String;)Ljava/lang/String;
  •  */
  • JNIEXPORT jstring JNICALL Java_com_sra_pipeline_servers_summarizer_JSummarizer_getSummary
  •   (JNIEnv *, jobject, jstring);
  •  
  • #ifdef __cplusplus
  • }
  • #endif
  • #endif
  •  
  •     
  •  
  • and the implementation
  • #ifndef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES
  • #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
  • #endif
  • #include "jsummarizer.h"
  • #include "inxight-summarizer.h"
  • #include "inxight-bstream.h"
  • #include "inxight-failure.h"
  • #include "inxight-bstream-intf.h"
  • #include <assert.h>
  •  
  • using namespace inxight;
  •  
  • static summarizer* summarzr;
  • static summarization_input_options* inopt; 
  • static summarization_sentence_output* sentOutput;
  • static summarization_phrase_output* phraseOutput;
  • /*
  •  * Class:     com_sra_pipeline_servers_summarizer_JSummarizer
  •  * Method:    createSummarizer
  •  * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
  •  */
  • JNIEXPORT jint JNICALL Java_com_sra_pipeline_servers_summarizer_JSummarizer_createSummarizer
  •   (JNIEnv *env, jobject object, jstring resource_dir, jstring license, jstring key) {
  •     const char* rdir;
  •     jboolean rdirCopy;
  •     rdir = env->GetStringUTFChars(resource_dir, &rdirCopy);
  •     if(rdir == NULL) {
  •         return 0; /*exception occurred*/
  •     }
  •     printf("rdir %s \n", rdir);
  •     const char* lic;
  •     jboolean licCopy;
  •     lic = env->GetStringUTFChars(license, &licCopy);
  •     if(lic == NULL) {
  •         return 0; /*exception ocurred*/
  •     }
  •     printf("lic %s \n", lic);
  •     const char* ckey;
  •     jboolean ckeyCopy;
  •     ckey = env->GetStringUTFChars(key, &ckeyCopy);
  •     if(ckey == NULL) {
  •         return 0; /* exception occurred */
  •     }
  •     printf("ckey %s \n", ckey);
  •     summarzr = new summarizer(rdir, lic, ckey);
  •     if(rdirCopy == JNI_TRUE) {
  •         env->ReleaseStringUTFChars(resource_dir, rdir);
  •     }
  •     if(licCopy == JNI_TRUE) {
  •         env->ReleaseStringUTFChars(license, lic);
  •     }
  •     if(ckeyCopy == JNI_TRUE) {
  •         env->ReleaseStringUTFChars(key, ckey);
  •     }
  •     return(1);
  • }
  •  
  • JNIEXPORT jint JNICALL Java_com_sra_pipeline_servers_summarizer_JSummarizer_setInOptions
  •   (JNIEnv *env, jobject object, jstring genre, jstring variant, jstring language) {
  •     const char *cgenre;
  •     jboolean genreCopy;
  •     cgenre = env->GetStringUTFChars(genre, &genreCopy);
  •     if(cgenre == NULL) {
  •         return 0; /*exception occurred */
  •     }
  •     const char *cvariant;
  •     jboolean cvarCopy;
  •     cvariant = env->GetStringUTFChars(variant, &cvarCopy);
  •     if(cvariant == NULL) {
  •         return 0; /*exception occurred*/
  •     }
  •     const char *clang;
  •     jboolean clangCopy;
  •     clang = env->GetStringUTFChars(language, &clangCopy);
  •     if(clang == NULL) {
  •         return 0;
  •     }
  •     inopt = new summarization_input_options(cgenre, cvariant, clang);
  •     if(genreCopy == JNI_TRUE) {
  •         env->ReleaseStringUTFChars(genre, cgenre);
  •     }
  •     if(cvarCopy == JNI_TRUE) {
  •         env->ReleaseStringUTFChars(variant, cvariant);
  •     }
  •     if(clangCopy == JNI_TRUE) {
  •         env->ReleaseStringUTFChars(language, clang);
  •     }
  •     return(1);
  • }
  •  
  • JNIEXPORT jint JNICALL Java_com_sra_pipeline_servers_summarizer_JSummarizer_setSentenceNum
  •   (JNIEnv *env, jobject object, jint sentCount, jboolean offset, jboolean nScore) {
  •     bool cOffset = offset ? true:false;
  •     bool cnScore = nScore ? true:false;
  •     unsigned int cnt = (unsigned int)sentCount;
  •     sentOutput = new summarization_sentence_output(cnt, cOffset, cnScore);
  •     return(1);
  • }
  •  
  • JNIEXPORT jint JNICALL Java_com_sra_pipeline_servers_summarizer_JSummarizer_setPhraseOpts
  •   (JNIEnv *env, jobject object, jint pCnt, jboolean pOffset) {
  •     unsigned int cCnt = (unsigned int)pCnt;
  •     bool offset = pOffset ? true:false;
  •     phraseOutput = new summarization_phrase_output(cCnt, offset);
  •     return(1);
  • }
  •  
  • JNIEXPORT jstring JNICALL Java_com_sra_pipeline_servers_summarizer_JSummarizer_getSummary
  •   (JNIEnv *env, jobject object, jstring filePath) {
  •     const char* cfile;
  •     jboolean cfileCopy;
  •     cfile = env->GetStringUTFChars(filePath, &cfileCopy);
  •     printf("cfile %s \n", cfile);
  •     if(cfile == NULL) {
  •         return 0;
  •     }
  •     file_byte_stream* fstream = new file_byte_stream(cfile);
  •     assert(fstream);
  •     assert(summarzr);
  •     assert(inopt);
  •     assert(sentOutput);
  •     assert(phraseOutput);
  •     printf("%s", "past fileio\n");
  •     printf("%s", "Before getSummary");
  •     summarization* summary = new summarization(*summarzr, *fstream,
  •                             *inopt, *sentOutput, *phraseOutput);
  •     printf("%s", "Past getSummary");
  •     const int sCnt = summary->number_of_key_sentences();
  •     const int pCnt = summary->number_of_key_phrases();
  •     sequence<key_item>::const_iterator it = summary->first_key_sentence();
  •     printf("sent# is %d", sCnt);
  •     int count = 0;
  •     for (;it != summary->end_key_sentence(); ++it, ++count) {
  •         const inxight::text line = it->item_text();
  •         printf("Sentence %i% \n", count);
  •         printf("[len %i%, %i% \n", line.length(), it->get_score());
  •         for(unsigned int i=0; i<line.length(); i++) {
  •             printf("%c%", line[i]);
  •         }
  •     }
  •     sequence<key_item>::const_iterator itr = summary->first_key_phrase();
  •     for (;itr != summary->end_key_phrase(); ++itr) {
  •         printf("%s%", itr->item_text());
  •     }
  •     if(cfileCopy == JNI_TRUE) {
  •         env->ReleaseStringUTFChars(filePath, cfile);
  •     }
  •     char* r = "results";
  •     return(env->NewStringUTF(r));
  • }
  • I started out by trying to get VC7 executables (cl and linker) to run in Eclipse using an ant script the way I usually do with gcc. Finally, I created a dll project in VC7 and added the header, JNI file and a .DEF file to it. However when I compiled and linked, the .lib file and obj file were created, but no dll and the following errors:

    dllproject error LNK2019: unresolved external symbol "__declspec(dllimport) class inxight::summarizer_interface * __cdecl inxight::make_summarizer(char const *,char const *,char const *)" (__imp_?make_summarizer@inxight@@YAPAVsummarizer_i nterface@1@PBD00@Z) referenced in function "public: __thiscall inxight::summarizer::summarizer(char const *,char const *,char const *)" (??0summarizer@inxight@@QAE@PBD00@Z)

    dllproject error LNK2019: unresolved external symbol "__declspec(dllimport) void __cdecl inxight::delete_summarizer(class inxight::summarizer_interface *)" (__imp_?delete_summarizer@inxight@@YAXPAVsummarize r_interface@1@@Z) referenced in function "public: virtual __thiscall inxight::summarizer::~summarizer(void)" (??1summarizer@inxight@@UAE@XZ)

    dllproject error LNK2019: unresolved external symbol "__declspec(dllimport) class inxight::summarization_interface * __cdecl inxight::make_summarization(class inxight::summarizer_interface &,class inxight::byte_stream_interface &,class inxight::summarization_input_options const &,class inxight::summarization_sentence_output const &,class inxight::summarization_phrase_output const &,char const *,unsigned int,char const *)" (__imp_?make_summarization@inxight@@YAPAVsummariza tion_interface@1@AAVsummarizer_interface@1@AAVbyte _stream_interface@1@ABVsummarization_input_options @1@ABVsummarization_sentence_output@1@ABVsummariza tion_phrase_output@1@PBDI5@Z) referenced in function "public: __thiscall inxight::summarization::summarization(class inxight::summarizer_interface &,class inxight::byte_stream_interface &,class inxight::summarization_input_options const &,class inxight::summarization_sentence_output const &,class inxight::summarization_phrase_output const &,char const *,unsigned int,char const *)" (??0summarization@inxight@@QAE@AAVsummarizer_inter face@1@AAVbyte_stream_interface@1@ABVsummarization _input_options@1@ABVsummarization_sentence_output@ 1@ABVsummarization_phrase_output@1@PBDI5@Z)

    dllproject error LNK2019: unresolved external symbol "__declspec(dllimport) void __cdecl inxight::delete_summarization(class inxight::summarization_interface *)" (__imp_?delete_summarization@inxight@@YAXPAVsummar ization_interface@1@@Z) referenced in function "public: virtual __thiscall inxight::summarization::~summarization(void)" (??1summarization@inxight@@UAE@XZ)

    dllproject error LNK2001: unresolved external symbol "public: __thiscall inxight::failure::failure(class inxight::failure const &)" (??0failure@inxight@@QAE@ABV01@@Z)

    dllproject error LNK2001: unresolved external symbol "public: __thiscall inxight::file_not_found::file_not_found(class inxight::file_not_found const &)" (??0file_not_found@inxight@@QAE@ABV01@@Z)

    dllproject error LNK2001: unresolved external symbol "public: virtual __thiscall inxight::file_not_found::~file_not_found(void)" (??1file_not_found@inxight@@UAE@XZ)

    dllproject error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall inxight::file_not_found::file_not_found(char const *,char const *)" (__imp_??0file_not_found@inxight@@QAE@PBD0@Z) referenced in function "private: void __thiscall inxight::file_byte_stream::open(char const *)" (?open@file_byte_stream@inxight@@AAEXPBD@Z)

    These functions exist in the API, one is as follows:
    Expand|Select|Wrap|Line Numbers
    1. INXIGHT_SUMMARIZER_EXPORT summarization_interface* make_summarization
    2.         (summarizer_interface& s,
    3.          inxight::byte_stream_interface& bstr,
    4.          const summarization_input_options& input_options,
    5.          const summarization_sentence_output& sentence_output_options,
    6.          const summarization_phrase_output& phrase_output_options,
    7.          const char* query_string,
    8.          size_t query_length,
    9.          const char* query_encoding);  
    The macro/preprocessor command INXIGHT_SUMMARIZER_EXPORT is conditionally set on whether the vendor's dll is being created or not.
    I have been through the compile and link command line for the C++ and JNI implementations and can find nothing that has to do with the vendor's code and dll.
    So why do these things show up in one implementation and not the other?
    Nov 15 '08 #1
    Share this Question
    Share on Google+
    9 Replies


    weaknessforcats
    Expert Mod 5K+
    P: 9,197
    What does your DEF file look like?

    Also, a DLL is a C structure. That means the function names have to be unique.

    I assume all of the function names you have in the DEF file are all extern "C" in the C++ code.

    The extern "C" also prevents your using member functions in the DEF file. You will need to write a wrapper for these.
    Nov 16 '08 #2

    P: 8
    The .def file:
    Expand|Select|Wrap|Line Numbers
    1. LIBRARY jsummarizer
    2. EXPORTS
    3. Java_com_sra_pipeline_servers_summarizer_JSummarizer_createSummarizer
    4. Java_com_sra_pipeline_servers_summarizer_JSummarizer_setInOptions
    5. Java_com_sra_pipeline_servers_summarizer_JSummarizer_setSentenceNum
    6. Java_com_sra_pipeline_servers_summarizer_JSummarizer_setPhraseOpts
    7. Java_com_sra_pipeline_servers_summarizer_JSummarizer_getSummary
    As is shown in the listing above for the JNI implementation these are all "JNIEXPORT"
    however a standard part of the javah generated header file is
    Expand|Select|Wrap|Line Numbers
    1. #ifdef _cplusplus
    2. extern "C" {
    3. #endif
    This fits inside the header guard statements/#def and the bracket encloses all the functions.
    The functions that end up being unresolved symbols are not ones from my code. They exist in the API and they are exported or imported apparently at the time that the API DLL is compiled or not. Never seen this before, where the vender's compilation instruction force themselves into my compilation.
    The only thing of concern from their code should be whether the function you want to use is exported, but then that's the whole point of a dll, their imports have never been an issue and are not in the C++ implimentation.
    Nov 17 '08 #3

    weaknessforcats
    Expert Mod 5K+
    P: 9,197
    If this is your DLL code:
    Expand|Select|Wrap|Line Numbers
    1. #include <iostream>
    2. using namespace std;
    3.  
    4. void __stdcall DisplayFromDll()
    5. {
    6.     cout << "This function was called from ADLL.dll" << endl;
    7. }
    8.  
    9. int __stdcall AreaOfSquare (int len, int wid)
    10. {
    11.     return len * wid;
    12. }
    13.  

    where __stdcall is WINAPI to Microsoft.

    Then your DEF file looks like:
    Expand|Select|Wrap|Line Numbers
    1. ;BEGIN ADLL.DEF FILE
    2. ;This DEF file is required becuase the argument to GetProcAddress()
    3. ;for the function is a C-string and it will never be equal to the
    4. ;C++ mangled name for the function
    5. ;This DEF file maps the mangled name to a name that can be used with GetProcAddress()
    6. ;Note also: Change project settings in Visual Studio to send the LINK this def file.
    7. ;Visual Studio.NET: Project Properties/Linker/Input/Module Definition File/...Path to the def file\Adll.def
    8. LIBRARY ADll 
    9. EXPORTS 
    10. ;Exported Name    C++ Mangled Name
    11. AreaOfSquare   =  ?AreaOfSquare@@YGHHH@Z
    12. DisplayFromDll =  ?DisplayFromDll@@YGXXZ
    13. ;END DEF FILE 
    14.  
    This code shows how to use the DLL:
    Expand|Select|Wrap|Line Numbers
    1. #include <iostream>
    2. using namespace std;
    3.  
    4. #include <windows.h>
    5.  
    6.  
    7.  
    8. int main()
    9. {
    10.  
    11.  
    12.  
    13.     cout << "Calling functions from a dll" << endl;
    14.  
    15.     //First, load the dll into memory
    16.     HMODULE theDll = LoadLibrary("C:\\Scratch\\ClassDemos\\ADll\\Debug\\ADll.dll");
    17.     if (!theDll)
    18.     {
    19.         cout << "The dll failed to load" << endl;
    20.         return 1;
    21.     }
    22.  
    23.     //Second, get the address of the desried function from the dll
    24.     FARPROC addr = GetProcAddress(theDll, "DisplayFromDll");
    25.     if (!addr)
    26.     {
    27.  
    28.         //Look up the error in the system errors list
    29.         unsigned int what = GetLastError();
    30.         if (what == ERROR_PROC_NOT_FOUND)
    31.         {
    32.             cout << "Function not found in the dll" << endl;
    33.         }
    34.         else
    35.         {
    36.             cout << "Error: " << what << endl;
    37.         }
    38.         return 2;
    39.     }
    40.     cout << "The function has been located in the dll" << endl;
    41.     //Declare a function pointer that can accept the address of the function.
    42.     //You will need to know the function prototype to do this.
    43.     //Dll function prototypes should be provided by the vendor of the dll
    44.     void (__stdcall *DisplayFromDll)();
    45.     //Type-cast the address returned from GetProcAddress to the function pointer type
    46.     DisplayFromDll = reinterpret_cast<void (__stdcall *)()>  (addr);
    47.     //Now use the function pointer to call the function:
    48.     DisplayFromDll();
    49.  
    50.     //If you don't use a .def file in the dll, you must use the mangled name
    51.     //Second, get the address of the desried function from the dll
    52.     addr = GetProcAddress(theDll, "AreaOfSquare");
    53.     if (!addr)
    54.     {
    55.  
    56.         //Look up the error in the system errors list
    57.         unsigned int what = GetLastError();
    58.         if (what == ERROR_PROC_NOT_FOUND)
    59.         {
    60.             cout << "Function not found in the dll" << endl;
    61.         }
    62.         else
    63.         {
    64.             cout << "Error: " << what << endl;
    65.         }
    66.         return 2;
    67.     }
    68.  
    69.     cout << "The function has been located in the dll" << endl;
    70.     //Declare a function pointer that can accept the address of the function.
    71.     //You will need to know the function prototype to do this.
    72.     //Dll function prototypes should be provided by the vendor of the dll
    73.     int (__stdcall *AreaOfSquare)(int, int);
    74.     //Type-cast the address returned from GetProcAddress to the function pointer type
    75.     AreaOfSquare = reinterpret_cast<int (__stdcall*)(int,int)>  (addr);
    76.     //Now use the function pointer to call the function:
    77.     cout << "The area of a 6x8 square is " << AreaOfSquare(6,8) << endl;;
    78.  
    79.     //Finally, unload the dll from memory
    80.     FreeLibrary(theDll);
    81.  
    82.     return 0;
    83. }
    84.  
    Any C++ class code should be called from the API functions. Those LNK2019 and LNK2001 look like some of your code is not in your build, like maybe you are missing a library.
    Nov 17 '08 #4

    P: 8
    Post Deleted by Poster
    Nov 18 '08 #5

    P: 8
    First, some clarification. The .DEF file I posted is not the one for the vendor's dll, it is for the JNI dll which I can't get to build. This is my first time using MSVC for one of these projects, usually use GNI g++/gcc package. Using it I usually see in the build output a section where the C++ manged names are being resolved to the Java methods I tag with the qualifier "native" in the Java code and the JNI signatures.
    The JNI file handles the Java - C/C++ interface and gives me a "native" environment to call native functions.
    The loading and unloading that you talked about all happens on the Java side, I use System.loadLibrary(<lib name>) to load the JNI dll, which has a dependency on the 3rd party dll and gets it loaded, but not directly as you showed. Unloading is handled implicitly or explicitly by Java's garbage collection. I will just need to clean up the 4 C++ objects I create.
    Got to thinking about what you said, and made sure that I had all the paths to libraries. Added a couple but no luck.
    Did however think about how the two projects are different. C++ built an exe mine builds a dll. In one of the vendor's .h files, specifically inxight-sum-declspec.h I found this song-and-dance:
    Expand|Select|Wrap|Line Numbers
    1. // -*- C++ -*- Copyright (C) 2002 Inxight Software Inc.  All Rights Reserved.
    2. #ifndef INXIGHT_SUM_DECLSPEC
    3. #define INXIGHT_SUM_DECLSPEC
    4.  
    5. // If we're compiling using the MSVC++ compiler, use declspec(dll[im|ex]port)
    6. // to control interface objects that are exported from the DLL.
    7. #if defined(_MSC_VER) && !defined(INXIGHT_BUILDING_SUMMARIZER_TEST)
    8. # ifdef INXIGHT_BUILDING_SUMMARIZER_DLL
    9. #  define INXIGHT_SUMMARIZER_EXPORT __declspec(dllexport)
    10. # else
    11. #  define INXIGHT_SUMMARIZER_EXPORT __declspec(dllimport)
    12. # endif
    13. #else
    14. # define INXIGHT_SUMMARIZER_EXPORT
    15. #endif
    16.  
    17.  
    18. #endif
    In the C++ project, I was actually working under their test project so INXIGHT_BUILDING_SUMMARIZER_TEST would have been defined so it would fail through at that point. On the dll project it would pass the first line and because I'm not building the Summarizer dll (Summarizer37.dll) it falls into the first # else. This certainly matches the value of INXIGHT_SUMMARIZER_EXPORT that is showing up in the errors.
    Now my understanding is that this is happening because I am building against the .lib files. My info is that when you do that you are actually pulling the vendor's functionality into your dll, which makes their preprocessor directives in scope. Does that make sense? This is the first time I've had .libs available, normally I build against the dll. Will try building it that way.
    BTW looked up your profile. Your an inspiration to me, to still be actively involved in this field at your age is commendable, born in 46 here our generation continues to make contributions, and I my feeling is we're better off for staying involved. Thanks
    Jim
    Nov 18 '08 #6

    P: 8
    Tried it with only the primary DLL i.e. Summarizer37.dll and all the errors went away. Unfortunately, I now have a LNK1136 error "invalid or corrupt file" have tried all the remedies MS advocates, any ideas?
    Jim
    Nov 18 '08 #7

    P: 8
    Apparently linker.exe does not link against a dll, and that is source of the LNK1136 error. Finally got it to work. Was including too many .lib files in the project. I included only summarizer.lib and platform37.lib and it compiled. When I put the dll in my Java project and tried to call it I got an error. At least I have the command line to use in my ant script so will keep at it.
    Thanks very much
    Jim
    Nov 18 '08 #8

    weaknessforcats
    Expert Mod 5K+
    P: 9,197
    [quote=jjones7947]
    Did however think about how the two projects are different. C++ built an exe mine builds a dll.
    [/code]

    What does that mean??

    C++ does not build an exe. Are you referring to MSVC? If so, and it is building a exe, you have the wrong project type. Am I just hallucinating here?
    Nov 18 '08 #9

    P: 8
    Yes using MSVC, and the C++ project was mostly to ensure that I could hang on to the 4 setup objects (summarizer, inputopts, sentenceopts, and phraseopts) and have them available and valid when I called the final constructor for summarization. In that sense it was successful. So I didn't try the next step of building a dll with the C++ code which I guess would make it an extension of the vendor's library. Instead I skipped to compiling the JNI code into a dll, which is where I had the problem. But did get it to build finally.
    When I called it from Java I could call the function that creates the summarizer object, the one that creates the input_options object, the sentence-options and the phrase_options; with no problems. It fails when I try to pass all those objects + the byte stream to the constructor for summarization. My print statements show me that it never gets past that step.
    This does indicate that the Java code is communicating with the JNI which in turn is communicating with the vendor's dll. According to the error file that Java generates the Problematic frame is in kernel32.dll + 0x12a5b.
    I've asserted the pointers to the first 5 objects and they pass, but I realized that only meant they had been assigned, and not much else. They surely point to an address, but I don't know how to determine whether that address still holds the value I placed there.
    If I place a "DeBug()" statement before that problem line and look at the objects in VC7 debug, it appears they are all valid, in that they have addresses.
    The stak from the Java error file is:
    Stack: [0x003a0000,0x003f0000), sp=0x003ef2e4, free space=316k
    Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
    C [kernel32.dll+0x12a5b]
    C [summarizer37.dll+0x1e583]
    C [summarizer37.dll+0x17e14]
    C [summarizer37.dll+0x15c55]

    Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
    j com.sra.pipeline.servers.summarizer.JSummarizer.ge tSummary(Ljava/lang/String;)Ljava/lang/String;+0
    j com.sra.pipeline.servers.summarizer.JSummarizer.do Summarization(Ljava/lang/String;)V+10
    j com.sra.pipeline.servers.summarizer.JSummarizer.ma in([Ljava/lang/String;)V+58
    v ~StubRoutines::call_stub
    I've been in this place before I went off to try the VC7 projects, and don't know where to go from here.
    Jim
    Nov 18 '08 #10

    Post your reply

    Sign in to post your reply or Sign up for a free account.