Newbie question about connecting C++ with Java with JNI

W

wignas

Hi all, I have a question and would really appreciate any help with
this. (Sorry for double posting but not sure in which group I should
post this)

So, I have connected a Java class and a Visual Studio C++ Dll-project
using JNI, here is the C++ code:

#include <windows.h>
#include <string.h>
#include "prog1.h" //The machine generated header file
#include "Logic.h" //I want to use the methods in this header

BOOL WINAPI DllMain(HANDLE hHandle, DWORD dwReason, LPVOID lpReserved)
{
return TRUE;

}

JNIEXPORT jint JNICALL Java_prog1_Sum(JNIEnv *, jclass, jint a, jint b)
{
//TestJava(); //This wont work :(
return a + b;

}

JNIEXPORT jstring JNICALL Java_prog1_saySomething(JNIEnv * env, jclass,
jstring strString)
{
char *lpBuff = (char*)env->GetStringUTFChars(strString, 0);
_strupr(lpBuff);
jstring jstr = env->NewStringUTF(lpBuff);
env->ReleaseStringUTFChars(strString, lpBuff);
return jstr;

}

I have tested to use this JNI-methods from Java and it works fine, but
now I want call my old C/C++ methods in "Logic.h" from this JNI
interface. How do I do that? Say I have a simple method in Logic.c like
this:

extern void TestJava()
{
CAN_DATA_WriteConvX myConv1Settings;
myConv1Settings.Motor0 = MotorOn;
outputConv1(myConv1Settings);

}

I can't call this from my JNIEXPORT methods, but I can call it from any
other "ordinary" cpp method. So how should I do for using the old
methods in Logic.h from Java?

Thanks for any help. /Jonas
 
G

Gordon Beaton

I can't call this from my JNIEXPORT methods, but I can call it from any
other "ordinary" cpp method. So how should I do for using the old
methods in Logic.h from Java?

You can call any methods or functions you like from your JNI methods.
What didn't work, exactly?

Include Logic.h in your JNI source file as you've done here. Compile
both source files and link them together when you build your DLL.

/gordon
 
W

wignas

Gordon said:
You can call any methods or functions you like from your JNI methods.
What didn't work, exactly?

Well, I get a linking error (I'm using Visual Studio) like this:

1>Linking...
1>JavaCon.obj : error LNK2001: unresolved external symbol "void __cdecl
TestJava(void)" (?TestJava@@YAXXZ)
1>.\Debug\ConvDemoApplication.dll : fatal error LNK1120: 1 unresolved
externals

This is when I try to use the TestJava() method in Logic.c and I have
included Logic.h in my JNI source file.

Any suggestions?

Thank you.
 
G

Gordon Beaton

Well, I get a linking error (I'm using Visual Studio) like this:

1>Linking...
1>JavaCon.obj : error LNK2001: unresolved external symbol "void __cdecl
TestJava(void)" (?TestJava@@YAXXZ)
1>.\Debug\ConvDemoApplication.dll : fatal error LNK1120: 1 unresolved
externals

Then you need to declare the exported function properly in Logic.[ch],
to get rid of the link error. Sorry this isn't a JNI issue, and I
can't help you with visual studio.

One suggestion though. If you haven't already done so, declare the
function inside an extern "C" block in Logic.h as follows, and make
sure Logic.c includes Logic.h.

extern "C" {
extern void TestJava(void);
}

/gordon
 
T

Thomas Fritsch

Well, I get a linking error (I'm using Visual Studio) like this:

1>Linking...
1>JavaCon.obj : error LNK2001: unresolved external symbol "void __cdecl
TestJava(void)" (?TestJava@@YAXXZ)
1>.\Debug\ConvDemoApplication.dll : fatal error LNK1120: 1 unresolved
externals

This is when I try to use the TestJava() method in Logic.c and I have
included Logic.h in my JNI source file.

Any suggestions?
How exactly looks your declaration of function Test() in file "Logic.h"?
I guess you simply have:
extern void __cdecl TestJava();

When you include your "Logic.h" from a C source "*.c" and from a C++
source "*.cpp", the C and C++ compilers generate 2 different function
symbols: "TestJava" and "?TestJava@@YAXXZ".
At least that would explain your link error.

You should try the usual idiom to supress the C++ name mangling:
/* __cplusplus is automatically set by the C++ compiler */
#ifdef __cplusplus
extern "C" {
void __cdecl TestJava(void);
}
#else
extern void __cdecl TestJava(void);
#endif
 
W

wignas

Thomas Fritsch skrev:
You should try the usual idiom to supress the C++ name mangling:
/* __cplusplus is automatically set by the C++ compiler */
#ifdef __cplusplus
extern "C" {
void __cdecl TestJava(void);
}
#else
extern void __cdecl TestJava(void);
#endif

Thank you very much, it worked with this code! Thanks to Gordon as
well. :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top