Two Laptop Bag
The moose likes C / C++ and the fly likes Make .dll for JNI from existing C++ (Windows) Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Languages » C / C++
Bookmark "Make .dll for JNI from existing C++ (Windows)" Watch "Make .dll for JNI from existing C++ (Windows)" New topic

Make .dll for JNI from existing C++ (Windows)

Alvin Parker
Ranch Hand

Joined: Oct 01, 2013
Posts: 39
I need to construct a dynamic link library from existing C++ code. My understanding of C++ is rudimentary. I have, however, used JNI in the past to communicate with DLL's but they've always been DLL's provided to me by the vendor with well-documented API's so writing a wrapper and getting going has been easy.

Please keep in mind that I cannot use Runtime.exe() for this (at least I don't see how I could). The C++ code takes an observer which it notifies of messages when it has them. If there's some way to build the system so that I can use Runtime.exe, I'm open to that and feel that would be a better cross-platform solution anyway if I can get away with it. However, the target system that will use the DLL has already been built and it does work with an old DLL that I was able to secure for a previous version of the C++ code. Still, I'd be happy to modify the Java side if it means getting a better and quicker solution from the C++ side.

The C++ source is from an open source project (rtmidi). I know that Java has MIDI packages. We have found javax.sound to be unreliable when it comes to many people's systems - sound drops out when students are playing along with our accompaniments and MIDI cables get lost and / or cannot be found at all. I was able to use an old version of the rtmidi packages (someone made a wrapper for them for the old version) and prove that none of these problems exist with this package. However, there's a memory leak problem in the old C++ code, they've reported it as fixed but the project is not well supported and the build files are for the old version and don't work when I simply change the C++ source and update the directory name in the build scripts. I now need to make new build files and have no clue how to get a DLL out.

The instructions for building on Windows are to add the pre-compiler flags as such :

1. "__WINDOWS_MM__". This flag tells the C++ program which API to load when you call it. So this flag needs to be somewhere in my build command such that the DLL will automatically send this flag when I invoke "new" on the RtMidi.
2. "winmm.lib" is a dependency I think. However, I am not sure if this is needed if you're not using Visual C++. I would prefer to use MinGW if I can.
3. "multithreaded"

That's about the extent of the instructions they give. The rest just says "compiler specific".

So... can someone please tell me what I need to do (or resources I need to go study) to make a DLL that I can then call with JNI to invoke the DLL and C++ code?

My directory structure is /rtmidi-2.0.1 which has the RtMidi.h, RtError.h and RtMidi.cpp in it. There is an old MS Visual Studio build script for version 1.0 (not 2.0.1) provided but it won't make a DLL (but will compile) and my attempts at doing so have all failed. Can someone help me understand how to create this DLL in such a way that I can then write my JNI wrapper and be on my way, please? If I need to provide more info, please do let me know and thanks so much for your help!
Alvin Parker
Ranch Hand

Joined: Oct 01, 2013
Posts: 39
Given that this has sat here for a few days, I'm guessing my question is too vague or that I'm trying to do something that is rarely needed to be done by programmers. Is there anyone who knows of a tutorial or resources I can find that will help me take existing C++ code, make a DLL useable by JNI from it and explain how to use the compiler flags with MinGW (or VC++ if that's easier)? Alternatively, is there anyone who can give me just the command line args I would need to run MinGW to produce the artifact I'm aiming for?
Luke Leber
Ranch Hand

Joined: Sep 20, 2013
Posts: 69

A bit late of a reply, but if you're using mingw to build a DLL to access from JNI, you need to provide the --kill-at flag so that the correct calling convention will be used. This can be done through your IDE's compiler options dialog. Judging from the preprocessor kludge needed to build successfully on Windows anyway, you're going to have fun.

Also, you will have to provide builds for both 32 and 64 bit JREs.
I agree. Here's the link:
subject: Make .dll for JNI from existing C++ (Windows)
It's not a secret anymore!