0

for my current project I need to use some c++ code from within my java application. It seems to me that the common solution is to create a DLL out of the c++ part and access it via JNA. As I'm a total beginner when it comes to c++ I figure I start with a minimal basis and continue work from there. However I can't even bring these minimal example to run. Here's what I did:

I used documentation for Visual Studio to create my DLL (found here: https://msdn.microsoft.com/de-de/library/ms235636.aspx)

What you do there is that you define a header

// MathFuncsDll.h

#ifdef MATHFUNCSDLL_EXPORTS
#define MATHFUNCSDLL_API __declspec(dllexport) 
#else
#define MATHFUNCSDLL_API __declspec(dllimport) 
#endif
namespace MathFuncs
{
 // This class is exported from the MathFuncsDll.dll
 class MyMathFuncs
 {
 public: 
    // Returns a + b
    static MATHFUNCSDLL_API double Add(double a, double b); 
 };
}

and a .cpp file

// MathFuncsDll.cpp : Defines the exported functions for the DLL application.

#include "stdafx.h"
#include "MathFuncsDll.h"
#include <stdexcept>

using namespace std;

namespace MathFuncs
{
 double MyMathFuncs::Add(double a, double b)
 {
    return a + b;
 }
}

And then build it into a DLL. So far this worked without error. I then proceeded to write a small Java Programm to access this DLL via JNA, again sticking to the JNA Documentation:

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;

/** Simple example of JNA interface mapping and usage. */
public class HelloWorld {

  // This is the standard, stable way of mapping, which supports extensive
  // customization and mapping of Java to native types.

  public interface CLibrary extends Library {
      CLibrary INSTANCE = (CLibrary) Native.loadLibrary((Platform.isWindows() ? "zChaffDLL" : "c"), CLibrary.class);

      double Add(double a, double b);
  }

  public static void main(String[] args) {
      CLibrary.INSTANCE.Add(5d, 3d);

  }
}

Running this results in this error: Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'Add': the specified procedure could not be found.

I tinkered around a bit but couldn't solve the problem. At this point I'm pretty much lost since I don't see myself able to construct an even easier example - so any help or pointers would be really appreciated.

dhyr
  • 21
  • 3
  • C++ and C have different interfaces (ABIs), the fact that you're loading a C++ library with a ```CLibrary``` type, already looks suspicious to me. Also see: [Java Native Access doesn't do C++, right?](http://stackoverflow.com/questions/2241685/java-native-access-doesnt-do-c-right). You might be better of using JNI instead, though it's a bit more work. – Jorn Vernee Apr 25 '16 at 16:29

1 Answers1

1

C++ "mangles" exported names according to the compiler's whims. For example, "void main(argc, argv)" might come out as "_Vmain_IPP@xyzzy".

Run depends.exe on your DLL to see what the exported names look like. extern "C" in your code will prevent C++ from mangling exported function names.

JNA handles static functions just fine; JNAerator accommodates some extra mangling automatically, but if you want to map C++ classes onto Java classes, you're better off with something like SWIG.

technomage
  • 9,861
  • 2
  • 26
  • 40
  • I tried to use extern "C" but it didn't help. depends.exe shows the correct function names but has a ? in front of them. So far I couldn't figure out why that is – dhyr Apr 26 '16 at 08:27
  • Show the updated source and the depends.exe output in your question. – technomage Apr 26 '16 at 18:38