C++ dllexport/dllimport

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • jjones7947
    New Member
    • Nov 2008
    • 8

    C++ dllexport/dllimport

    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
    Code:
    void createSummarizer(char* rdir, char* lFile, char* key);
    void createInputOptions(const char* genre, const char* variant, const char* lang, const char* encoding, const char* format);
    void setSentenceOutput(unsigned int sentences_wanted, bool sentence_offset_only, bool normalize_score);
    void setPhraseOutput(unsigned int phrases_wanted, bool phrase_offset_only);
    void getSummary(const char* fileName);
    The implementation
    Code:
    #include "inxight-summarizer.h"
    #include "inxight-charptr.h"
    #include "inxight-text.h"
    #include "inxight-bstream.h"
    #include "inxight-unicode.h"
    #include "inxight-unicode-utils.h"
    #include <iostream>
    #include <sys/timeb.h>  // for ftime
    #include <assert.h>
    
    using namespace inxight;
    
    static summarizer* summarzr;
    static summarization_input_options* inopt; 
    static summarization_sentence_output* sentOutput;
    static summarization_phrase_output* phraseOutput;
    
    void createSummarizer(char* rdir, char* lFile, char* key)
    {
    	summarzr = new summarizer(rdir, lFile, key);
    }
    
    void createInputOptions(const char* genre, const char* variant, const char* lang, const char* encoding, const char* format)
    {
    	inopt = new summarization_input_options(genre, variant, lang, encoding, format);
    }
    
    void setSentenceOutput(unsigned int sentences_wanted, bool sentence_offset_only, bool normalize_score)
    {
    	sentOutput = new summarization_sentence_output(sentences_wanted, sentence_offset_only, normalize_score);
    }
    
    void setPhraseOutput(unsigned int phrases_wanted, bool phrase_offset_only)
    {
    	phraseOutput = new summarization_phrase_output(phrases_wanted, phrase_offset_only);
    }
    
    void getSummary(const char* fileName)
    {
    	file_byte_stream* fs = new file_byte_stream(fileName);
    	assert(fs);
    	assert(summarzr);
    	assert(inopt);
    	assert(sentOutput);
    	assert(phraseOutput);
    	summarization* summary;
    	summary = new summarization(*summarzr, *fs, *inopt, *sentOutput, *phraseOutput);
    	sequence<key_item>::const_iterator it = summary->first_key_sentence();
    	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]);
    		}
    		printf("%s%","\n");
    	}
    	printf(" There are %i key phrases: ", summary->number_of_key_phrases());
    	sequence<key_item>::const_iterator itr = summary->first_key_phrase();
    	for (;itr != summary->end_key_phrase(); ++itr) {
    		printf("%s%", itr->item_text());
    	}
    }
    The driver file
    Code:
    #include "test.h"
    
    
    
    void main()
    {
    	char* rdir = "../lang";
    	char* lFile = "../lang/license.dat";
    	char* key = "705553544e1a694a5f59535b561a754a5f485b4e535554491a795557575b545e1a127069757913";
    	const char* genre = "std";
    	const char* variant = "std";
    	const char* lang = "english";
    	const char* encoding = "cp_1252";
    	const char* format = "html";
    	unsigned int sentences_wanted = 5;
    	bool sentence_offset_only = false;
    	bool normalize_score = false;
    	unsigned int phrases_wanted = 0;
    	bool phrase_offset_only = false;
    	const char* fileName = "aaawgqM4Ob.html";
    
    	createSummarizer(rdir, lFile, key);
    	createInputOptions(genre, variant, lang, encoding, format);
    	setSentenceOutput(sentences_wanted, sentence_offset_only, normalize_score);
    	setPhraseOutput(phrases_wanted, phrase_offset_only);
    	getSummary(fileName);
    }
    Then I put together the JNi implementation
    header file
    Code:
    /* DO NOT EDIT THIS FILE - it is machine generated */
    [CODE]#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_STAND ARD_NAMES
    #define _CRT_SECURE_CPP _OVERLOAD_STAND ARD_NAMES 1
    #endif
    #include "jsummarize r.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_i nput_options* inopt;
    static summarization_s entence_output* sentOutput;
    static summarization_p hrase_output* phraseOutput;
    /*
    * Class: com_sra_pipelin e_servers_summa rizer_JSummariz er
    * Method: createSummarize r
    * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
    */
    JNIEXPORT jint JNICALL Java_com_sra_pi peline_servers_ summarizer_JSum marizer_createS ummarizer
    (JNIEnv *env, jobject object, jstring resource_dir, jstring license, jstring key) {
    const char* rdir;
    jboolean rdirCopy;
    rdir = env->GetStringUTFCh ars(resource_di r, &rdirCopy);
    if(rdir == NULL) {
    return 0; /*exception occurred*/
    }
    printf("rdir %s \n", rdir);
    const char* lic;
    jboolean licCopy;
    lic = env->GetStringUTFCh ars(license, &licCopy);
    if(lic == NULL) {
    return 0; /*exception ocurred*/
    }
    printf("lic %s \n", lic);
    const char* ckey;
    jboolean ckeyCopy;
    ckey = env->GetStringUTFCh ars(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->ReleaseStringU TFChars(resourc e_dir, rdir);
    }
    if(licCopy == JNI_TRUE) {
    env->ReleaseStringU TFChars(license , lic);
    }
    if(ckeyCopy == JNI_TRUE) {
    env->ReleaseStringU TFChars(key, ckey);
    }
    return(1);
    }

    JNIEXPORT jint JNICALL Java_com_sra_pi peline_servers_ summarizer_JSum marizer_setInOp tions
    (JNIEnv *env, jobject object, jstring genre, jstring variant, jstring language) {
    const char *cgenre;
    jboolean genreCopy;
    cgenre = env->GetStringUTFCh ars(genre, &genreCopy);
    if(cgenre == NULL) {
    return 0; /*exception occurred */
    }
    const char *cvariant;
    jboolean cvarCopy;
    cvariant = env->GetStringUTFCh ars(variant, &cvarCopy);
    if(cvariant == NULL) {
    return 0; /*exception occurred*/
    }
    const char *clang;
    jboolean clangCopy;
    clang = env->GetStringUTFCh ars(language, &clangCopy);
    if(clang == NULL) {
    return 0;
    }
    inopt = new summarization_i nput_options(cg enre, cvariant, clang);
    if(genreCopy == JNI_TRUE) {
    env->ReleaseStringU TFChars(genre, cgenre);
    }
    if(cvarCopy == JNI_TRUE) {
    env->ReleaseStringU TFChars(variant , cvariant);
    }
    if(clangCopy == JNI_TRUE) {
    env->ReleaseStringU TFChars(languag e, clang);
    }
    return(1);
    }

    JNIEXPORT jint JNICALL Java_com_sra_pi peline_servers_ summarizer_JSum marizer_setSent enceNum
    (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_s entence_output( cnt, cOffset, cnScore);
    return(1);
    }

    JNIEXPORT jint JNICALL Java_com_sra_pi peline_servers_ summarizer_JSum marizer_setPhra seOpts
    (JNIEnv *env, jobject object, jint pCnt, jboolean pOffset) {
    unsigned int cCnt = (unsigned int)pCnt;
    bool offset = pOffset ? true:false;
    phraseOutput = new summarization_p hrase_output(cC nt, offset);
    return(1);
    }

    JNIEXPORT jstring JNICALL Java_com_sra_pi peline_servers_ summarizer_JSum marizer_getSumm ary
    (JNIEnv *env, jobject object, jstring filePath) {
    const char* cfile;
    jboolean cfileCopy;
    cfile = env->GetStringUTFCh ars(filePath, &cfileCopy);
    printf("cfile %s \n", cfile);
    if(cfile == NULL) {
    return 0;
    }
    file_byte_strea m* fstream = new file_byte_strea m(cfile);
    assert(fstream) ;
    assert(summarzr );
    assert(inopt);
    assert(sentOutp ut);
    assert(phraseOu tput);
    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_it em>::const_iter ator it = summary->first_key_sent ence();
    printf("sent# is %d", sCnt);
    int count = 0;
    for (;it != summary->end_key_senten ce(); ++it, ++count) {
    const inxight::text line = it->item_text();
    printf("Sentenc e %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_it em>::const_iter ator itr = summary->first_key_phra se();
    for (;itr != summary->end_key_phrase (); ++itr) {
    printf("%s%", itr->item_text()) ;
    }
    if(cfileCopy == JNI_TRUE) {
    env->ReleaseStringU TFChars(filePat h, cfile);
    }
    char* r = "results";
    return(env->NewStringUTF(r ));
    }[/CODE]

    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(dll import) class inxight::summar izer_interface * __cdecl inxight::make_s ummarizer(char const *,char const *,char const *)" (__imp_?make_su mmarizer@inxigh t@@YAPAVsummari zer_interface@1 @PBD00@Z) referenced in function "public: __thiscall inxight::summar izer::summarize r(char const *,char const *,char const *)" (??0summarizer@ inxight@@QAE@PB D00@Z)

    dllproject error LNK2019: unresolved external symbol "__declspec(dll import) void __cdecl inxight::delete _summarizer(cla ss inxight::summar izer_interface *)" (__imp_?delete_ summarizer@inxi ght@@YAXPAVsumm arizer_interfac e@1@@Z) referenced in function "public: virtual __thiscall inxight::summar izer::~summariz er(void)" (??1summarizer@ inxight@@UAE@XZ )

    dllproject error LNK2019: unresolved external symbol "__declspec(dll import) class inxight::summar ization_interfa ce * __cdecl inxight::make_s ummarization(cl ass inxight::summar izer_interface &,class inxight::byte_s tream_interface &,class inxight::summar ization_input_o ptions const &,class inxight::summar ization_sentenc e_output const &,class inxight::summar ization_phrase_ output const &,char const *,unsigned int,char const *)" (__imp_?make_su mmarization@inx ight@@YAPAVsumm arization_inter face@1@AAVsumma rizer_interface @1@AAVbyte_stre am_interface@1@ ABVsummarizatio n_input_options @1@ABVsummariza tion_sentence_o utput@1@ABVsumm arization_phras e_output@1@PBDI 5@Z) referenced in function "public: __thiscall inxight::summar ization::summar ization(class inxight::summar izer_interface &,class inxight::byte_s tream_interface &,class inxight::summar ization_input_o ptions const &,class inxight::summar ization_sentenc e_output const &,class inxight::summar ization_phrase_ output const &,char const *,unsigned int,char const *)" (??0summarizati on@inxight@@QAE @AAVsummarizer_ interface@1@AAV byte_stream_int erface@1@ABVsum marization_inpu t_options@1@ABV summarization_s entence_output@ 1@ABVsummarizat ion_phrase_outp ut@1@PBDI5@Z)

    dllproject error LNK2019: unresolved external symbol "__declspec(dll import) void __cdecl inxight::delete _summarization( class inxight::summar ization_interfa ce *)" (__imp_?delete_ summarization@i nxight@@YAXPAVs ummarization_in terface@1@@Z) referenced in function "public: virtual __thiscall inxight::summar ization::~summa rization(void)" (??1summarizati on@inxight@@UAE @XZ)

    dllproject error LNK2001: unresolved external symbol "public: __thiscall inxight::failur e::failure(clas s inxight::failur e const &)" (??0failure@inx ight@@QAE@ABV01 @@Z)

    dllproject error LNK2001: unresolved external symbol "public: __thiscall inxight::file_n ot_found::file_ not_found(class inxight::file_n ot_found const &)" (??0file_not_fo und@inxight@@QA E@ABV01@@Z)

    dllproject error LNK2001: unresolved external symbol "public: virtual __thiscall inxight::file_n ot_found::~file _not_found(void )" (??1file_not_fo und@inxight@@UA E@XZ)

    dllproject error LNK2019: unresolved external symbol "__declspec(dll import) public: __thiscall inxight::file_n ot_found::file_ not_found(char const *,char const *)" (__imp_??0file_ not_found@inxig ht@@QAE@PBD0@Z) referenced in function "private: void __thiscall inxight::file_b yte_stream::ope n(char const *)" (?open@file_byt e_stream@inxigh t@@AAEXPBD@Z)

    These functions exist in the API, one is as follows:
    Code:
    INXIGHT_SUMMARIZER_EXPORT summarization_interface* make_summarization
            (summarizer_interface& s,
             inxight::byte_stream_interface& bstr,
             const summarization_input_options& input_options,
             const summarization_sentence_output& sentence_output_options,
             const summarization_phrase_output& phrase_output_options,
             const char* query_string,
             size_t query_length,
             const char* query_encoding);
    The macro/preprocessor command INXIGHT_SUMMARI ZER_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?
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    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.

    Comment

    • jjones7947
      New Member
      • Nov 2008
      • 8

      #3
      The .def file:
      Code:
      LIBRARY jsummarizer
      EXPORTS
      Java_com_sra_pipeline_servers_summarizer_JSummarizer_createSummarizer
      Java_com_sra_pipeline_servers_summarizer_JSummarizer_setInOptions
      Java_com_sra_pipeline_servers_summarizer_JSummarizer_setSentenceNum
      Java_com_sra_pipeline_servers_summarizer_JSummarizer_setPhraseOpts
      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
      Code:
      #ifdef _cplusplus
      extern "C" {
      #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.

      Comment

      • weaknessforcats
        Recognized Expert Expert
        • Mar 2007
        • 9214

        #4
        If this is your DLL code:
        Code:
        #include <iostream>
        using namespace std;
        
        void __stdcall DisplayFromDll()
        {
        	cout << "This function was called from ADLL.dll" << endl;
        }
        
        int __stdcall AreaOfSquare (int len, int wid)
        {
        	return len * wid;
        }

        where __stdcall is WINAPI to Microsoft.

        Then your DEF file looks like:
        Code:
        ;BEGIN ADLL.DEF FILE
        ;This DEF file is required becuase the argument to GetProcAddress()
        ;for the function is a C-string and it will never be equal to the
        ;C++ mangled name for the function
        ;This DEF file maps the mangled name to a name that can be used with GetProcAddress()
        ;Note also: Change project settings in Visual Studio to send the LINK this def file.
        ;Visual Studio.NET: Project Properties/Linker/Input/Module Definition File/...Path to the def file\Adll.def
        LIBRARY ADll 
        EXPORTS 
        ;Exported Name    C++ Mangled Name
        AreaOfSquare   =  ?AreaOfSquare@@YGHHH@Z
        DisplayFromDll =  ?DisplayFromDll@@YGXXZ
        ;END DEF FILE
        This code shows how to use the DLL:
        Code:
        #include <iostream>
        using namespace std;
        
        #include <windows.h>
        
        
        
        int main()
        {
        	
        	
        
        	cout << "Calling functions from a dll" << endl;
        
        	//First, load the dll into memory
        	HMODULE theDll = LoadLibrary("C:\\Scratch\\ClassDemos\\ADll\\Debug\\ADll.dll");
        	if (!theDll)
        	{
        		cout << "The dll failed to load" << endl;
        		return 1;
        	}
        
        	//Second, get the address of the desried function from the dll
        	FARPROC addr = GetProcAddress(theDll, "DisplayFromDll");
        	if (!addr)
        	{
        		
        		//Look up the error in the system errors list
        		unsigned int what = GetLastError();
        		if (what == ERROR_PROC_NOT_FOUND)
        		{
        			cout << "Function not found in the dll" << endl;
        		}
        		else
        		{
        			cout << "Error: " << what << endl;
        		}
        		return 2;
        	}
            cout << "The function has been located in the dll" << endl;
        	//Declare a function pointer that can accept the address of the function.
        	//You will need to know the function prototype to do this.
        	//Dll function prototypes should be provided by the vendor of the dll
        	void (__stdcall *DisplayFromDll)();
        	//Type-cast the address returned from GetProcAddress to the function pointer type
        	DisplayFromDll = reinterpret_cast<void (__stdcall *)()>  (addr);
        	//Now use the function pointer to call the function:
            DisplayFromDll();
        
        	//If you don't use a .def file in the dll, you must use the mangled name
        	//Second, get the address of the desried function from the dll
        	addr = GetProcAddress(theDll, "AreaOfSquare");
        	if (!addr)
        	{
        		
        		//Look up the error in the system errors list
        		unsigned int what = GetLastError();
        		if (what == ERROR_PROC_NOT_FOUND)
        		{
        			cout << "Function not found in the dll" << endl;
        		}
        		else
        		{
        			cout << "Error: " << what << endl;
        		}
        		return 2;
        	}
        
        	cout << "The function has been located in the dll" << endl;
        	//Declare a function pointer that can accept the address of the function.
        	//You will need to know the function prototype to do this.
        	//Dll function prototypes should be provided by the vendor of the dll
        	int (__stdcall *AreaOfSquare)(int, int);
        	//Type-cast the address returned from GetProcAddress to the function pointer type
        	AreaOfSquare = reinterpret_cast<int (__stdcall*)(int,int)>  (addr);
        	//Now use the function pointer to call the function:
            cout << "The area of a 6x8 square is " << AreaOfSquare(6,8) << endl;;
        
        	//Finally, unload the dll from memory
        	FreeLibrary(theDll);
        
        	return 0;
        }
        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.

        Comment

        • jjones7947
          New Member
          • Nov 2008
          • 8

          #5
          Post Deleted by Poster

          Comment

          • jjones7947
            New Member
            • Nov 2008
            • 8

            #6
            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.loadLibr ary(<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:
            Code:
            // -*- C++ -*- Copyright (C) 2002 Inxight Software Inc.  All Rights Reserved.
            #ifndef INXIGHT_SUM_DECLSPEC
            #define INXIGHT_SUM_DECLSPEC
            
            // If we're compiling using the MSVC++ compiler, use declspec(dll[im|ex]port)
            // to control interface objects that are exported from the DLL.
            #if defined(_MSC_VER) && !defined(INXIGHT_BUILDING_SUMMARIZER_TEST)
            # ifdef INXIGHT_BUILDING_SUMMARIZER_DLL
            #  define INXIGHT_SUMMARIZER_EXPORT __declspec(dllexport)
            # else
            #  define INXIGHT_SUMMARIZER_EXPORT __declspec(dllimport)
            # endif
            #else
            # define INXIGHT_SUMMARIZER_EXPORT
            #endif
            
            
            #endif
            In the C++ project, I was actually working under their test project so INXIGHT_BUILDIN G_SUMMARIZER_TE ST 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.d ll) it falls into the first # else. This certainly matches the value of INXIGHT_SUMMARI ZER_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

            Comment

            • jjones7947
              New Member
              • Nov 2008
              • 8

              #7
              Tried it with only the primary DLL i.e. Summarizer37.dl l 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

              Comment

              • jjones7947
                New Member
                • Nov 2008
                • 8

                #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

                Comment

                • weaknessforcats
                  Recognized Expert Expert
                  • Mar 2007
                  • 9214

                  #9
                  [quote=jjones794 7]
                  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?

                  Comment

                  • jjones7947
                    New Member
                    • Nov 2008
                    • 8

                    #10
                    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,0x00 3f0000), sp=0x003ef2e4, free space=316k
                    Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
                    C [kernel32.dll+0x 12a5b]
                    C [summarizer37.dl l+0x1e583]
                    C [summarizer37.dl l+0x17e14]
                    C [summarizer37.dl l+0x15c55]

                    Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
                    j com.sra.pipelin e.servers.summa rizer.JSummariz er.getSummary(L java/lang/String;)Ljava/lang/String;+0
                    j com.sra.pipelin e.servers.summa rizer.JSummariz er.doSummarizat ion(Ljava/lang/String;)V+10
                    j com.sra.pipelin e.servers.summa rizer.JSummariz er.main([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

                    Comment

                    Working...