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
Gordon Beaton - 17 Nov 2006 09:35 GMT
> 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

Signature
[ don't email me support questions or followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e
wignas@gmail.com - 17 Nov 2006 09:57 GMT
> 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.
Gordon Beaton - 17 Nov 2006 10:14 GMT
> Well, I get a linking error (I'm using Visual Studio) like this:
>
[quoted text clipped - 3 lines]
> 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

Signature
[ don't email me support questions or followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e
Thomas Fritsch - 17 Nov 2006 11:06 GMT
> Well, I get a linking error (I'm using Visual Studio) like this:
>
[quoted text clipped - 8 lines]
>
> 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

Signature
Thomas
wignas@gmail.com - 17 Nov 2006 13:33 GMT
Thomas Fritsch skrev:
> You should try the usual idiom to supress the C++ name mangling:
> /* __cplusplus is automatically set by the C++ compiler */
[quoted text clipped - 5 lines]
> extern void __cdecl TestJava(void);
> #endif
Thank you very much, it worked with this code! Thanks to Gordon as
well. :)