GetStringUTFChars function parameter - java-native-interface

I'm developing Android app using jni.
And I used GetStringUTFChars function as follows
jboolean iscopy;
const char* trainfile = (env)->GetStringUTFChars(jstr, &iscopy);
But I saw another example like this
const char *inCStr = (*env)->GetStringUTFChars(env, inJNIStr, NULL);
Both works well. But I cannot find any documentation about the former grammer even that is more concise.
Where Can I find the documentation, and Is there any difference between them?

The first example is C++ syntax and will work only in C++ programs. The second is for C programs.
The reason the two are different is that in C++ JNIEnv is a class and the functions are member functions of the env object, while in C JNIEnv is a pointer to a struct. Since what you receive as a parameter is a pointer to JNIEnv, in C you have to dereference it to access the struct members, that's why you must use *env in place of env.
This should be covered in any text on how to use JNI, but you can also find it by reading the code in the header file.

Related

LLVM automatic C++ linking

In some of the LLVM tutorials I'm seen where it's fairly easy to bind C function into a custom language based on LLVM. LLVM hands the programmer a pointer to the function that can be then be mixed in with the code being generated by LLVM.
What's the best method to do this with C++ libraries. Let's say I have a fairly complex library like Qt or Boost that I want to bind to my custom language. Do I need to create a stub library (like Python or Lua require), or does LLVM offer some sort of foreign function interface (FFI)?
In my LLVM code, I create extern "C" wrapper functions for this, and insert LLVM function declarations into the module in order to call them. Then, a good way to make LLVM know about the functions is not to let it use dlopen and search for the function name in the executing binary (this is a pain in the ass, since the function names need to be in the .dynsym section, and it is slow too), but to do the mapping manually, using ExecutionEngine::addGlobalMapping.
Just get the llvm::Function* of that declaration and the address of the function as given in C++ by &functionname converted to void* and pass these two things along to LLVM. The JIT executing your stuff will then know where to find the function.
For example, if you wanted to wrap QString you could create several functions that create, destroy and call functions of such an object
extern "C" void createQString(void *p, char const*v) {
new (p) QString(v); // placement-new
}
extern "C" int32_t countQString(void *p) {
QString *q = static_cast<QString*>(p);
return q->count();
}
extern "C" void destroyQString(void *p) {
QString *q = static_cast<QString*>(p);
q->~QString();
}
And create proper declarations and a mapping. Then you can call these functions, passing along a memory region suitably aligned and sized for QString (possibly alloca'ed) and a i8* pointing to the C string data for initialization.
If you compile some code in C++ and some in another language to LLVM bitcode, it should be perfectly possible to link these together and let one call the other... in theory.
In practice, you will need glue code to convert between the different language's types (e.g. there is no equivalent to a Python string in C++ unless you use CPython, so for void reverse(std::string s) to be callable with a str you need a conversion - worse, the whole object model is very different). And Qt specifically has a lot of magic that may require much more effort to expose after compilations. Also, there may be further potential problems I'm not aware of.
And even if that works, it's potentially very ugly to use. There are still get* and set* functions all over PyQt despite Python's very convenient descriptors - and much effort went into PyQt, they didn't just create some stubs.

How to call a c++ function using c && redirect application output to textEdit in Qt

I'm trying to do a couple of things at once. I'm trying to do one major thing: redirect the application output that is displayed in the Qt Creator console to a textEdit that I have on my GUI. However, the class that I need to do this in is written in C and all of its related headers are in C as well. Is there a way that I can redirect the output into the textEdit within the C class?
If you can modify the C code, you could allow it to take a callback such that text is sent to the callback function, instead of being merely printed with printf. For example, you could have something like:
void someFunctionInC
(
/* other parameters ... */
void (*printcallback)(const char* text, void* extra_arg),
void* extra_arg
)
{
/* ... */
printcallback("Hello world\n",extra_arg); /* instead of using printf */
/* ... */
}
You could then, in C++, create a callback that casts the void* extra_arg parameter back to a class and invokes a method on that class with the given text. Another possibility is you could use snprintf and create a variant of your C function that will print to a string instead of printing to standard out. Note that these solutions all require you to be able to modify the given C function. If it's absolutely not possible to modify the C function, you could use close, pipe, dup2, etc. to redirect stdout to a pipe and then read back the results from the pipe, but that is a really, really ugly solution. Good luck.
See http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.8
Interfacing C++ and C functions involves working around the name mangling that takes place by default in C++ to support function overloading.
To call a C++ function from a C function you must declare the C++ function with extern "C" qualifier. That instructs the compiler to leave its name unmangled.
To call a C function from a C++ function, you must prototype it with extern "C" in the scope of the C++ function.
This is a bit old, but take a look here. It seems like QTextStream is the answer, but the specifics I'm not sure about.
QProcess is QIODevice. If you are invoking this C programm, you may use QProcess and read it's output from it with QProcess::readAll* members

How to call a C++ function that takes a reference from C# code

HI,
I have a C++ function like the following:
int ShowJob(const JobData& data);
How does this translate to a DLLImport statement which I can use to call the function from C#?
I'd guess it behaves like a pointer under the hood, so treat it as such. Ironically, this is done by declaring it as a reference parameter.
[DLLImport(DLLName)]
public static extern int ShowJob(ref JobData data);
This could only work if JobData is a structure. You're dead in the water if it is a class, you cannot create a C++ class instance in C#. You don't have access to the constructor and destructor.
The "const" keyword is an attribute checked by the C++ compiler, it has no relevance to C# code. A C++ reference is a pointer under the hood, you'll get one by declaring the argument with "ref". You're likely to have a problem getting the "ShowJob" export name right, it is normally decorated by the C++ compiler. You'd suppress that decoration by prefixing the function with extern "C" in the C++ code. If you cannot change the C++ code then you can find the exported name by running Dumpbin.exe /exports on the DLL.
Putting this all together, the declarations ought to resemble something like this:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
private struct JobData {
// members...
}
[DllImport("something.dll", EntryPoint = "?ShowJob##YAHABUJobData###Z", CallingConvention = CallingConvention.Cdecl)]
private static extern int ShowJob(ref JobData data);
Lot's of guess work going on here, you'll need to verify this with your actual C++ code. If the JobData argument is in fact a class then you'll need to write a ref class wrapper in the C++/CLI language.

ESP Error when I call an API function?

platform : win32 , language : c++
I get this error when I call an imported function I declared:
Run-Time Check Failure #0 - The value of ESP was not properly saved
across a function call. This is
usually a result of calling a function
declared with one calling convention
with a function pointer declared with
a different calling convention.
And this is the code I used:
int LoadSongFromFile(int module);
typedef int (CALLBACK* loadSongT)(LPCTSTR);
//...
HINSTANCE dllHandle = NULL;
loadSongT loadSongPtr = NULL;
dllHandle = LoadLibrary(L"miniFMOD.dll");
loadSongPtr = (loadSongT)GetProcAddress(dllHandle,"SongLoadFromFile");
int songHandle = loadSongPtr(L"C:\b.xm");
The function I'm trying to call is SongLoadFromFile which requires one argument (in C# it is string so I assume its LPCTSTR in C++) and returns an int value.
Can somebody check what have I done wrong?
P.S. songHandle gets a weird negative value of -858993460
This is how I can call that function from C# :
[DllImport("MiniFMOD.dll")] public static extern int SongLoadFromFile(string name);
P.S. 2 : Using *typedef int (__cdecl loadSongT)(char);* doesn't return an error but songHandle comes up as 0.
miniFMOD.dll is an unmanaged library
I think the other people are misunderstanding the question. It seems to me that minifmod.dll is a native library that exports a function named SongLoadFromFile. The existing code that calls this is managed code (C#) that uses DllImport to call the function in the native DLL. From what little information I could gather by a few Google searches, it looks as though it should be declared as follows:
typedef int (__cdecl * SongLoadFromFileT)(const char*);
Importantly, it is __cdecl calling convention and it takes an ANSI string instead of a Unicode string.
As an aside, I find it strange that I can't find ANYTHING on minifmod.dll other than a few forum posts on a Russian website and some SO questions from this guy. The only "legitimate" information I can find on minifmod is a small static library with similar functionality. I wonder if minifmod.dll is some kind of commercialized version of the static library; at least that would explain why there is not much public documentation about it.
Ah, I found it; it is a Delph port of minifmod (http://www.cobans.net/minifmod.php).
You need to make sure to specify the right calling convention in your function pointer prototype ('CALLBACK' might be the wrong choice).
The calling code uses the calling convention not matching that of the function being called. See this very similar question. You need to open the header defining that function (should come with the library you try to use), look the convention up and change your function pointer declaartion accordingly.

How to call a JNI DLL from C++

I have a task to interface with a dll from a third party company using C++.
The dll package comes with:
the dll itself
a sample Java implementation - consists of a java wrapper(library) generated using the SWIG tool and the the java source file
documentation that states all the public datatypes, enumeration and member functions.
My other colleague is using Java(based on the example in package) to interface with the dll while I'm asked to use C++. The Java example looks straight forward... just import the wrapper and instantiate any class described in the docs..
More info on the dll:
From the docs, it says the dll was programmed using C++
From a hexdump, it shows that it was compiled using VC90 (VS C++ 2008 right?) and something from Dinkumware.
From a depends.exe output, the functions seems to be wrapped under JNI. For example: _Java_mas_com_oa_rollings_as_apiJNI_Server_1disconnect#20
My dilemma:
The dll company is not changing anything in the dll and not providing any other info.
How do i use the member functions in the class from the dll?
I did some simple LoadLibrary() and GetProcAddress and manage to get the address of the public member functions.
But i dunno how to use the functions that has the datatype parameters defined in the dll. For example:
From the docs, the member function is defined as:
void Server::connect(const StringArray, const KeyValueMap) throw(std::invalid_argument,std::out_of_range)
typedef std::map Server::KeyValueMap
typedef std::vector Server::StringArray
how do i call that function in C++. The std::map and std::vector in my compiler (VS 2005) has different functions listing that the one in the dll. For example, from the depends.exe output:
std::map // KeyValueMap - del, empty, get, has_1key,set
std::vector // StringArray - add, capacity, clear, get, isEMPTY, reserve, set, size
Any advice/strategy on how i should solve this? Is it possible to simply instantiate the class like the Java example?
If you are trying to use VS 2005 to try and interface with a DLL that is built using VS2008, your attempts will be mostly doomed unless you can use a plain C interface. Given your description, this is not the case; The runtime libraries differ between VS2005 and VS2008 so there is little chance that the object layout has stayed the same between compilers. The 'something from Dinkumware' that you're referring to is most likely the C++ standard library as ISTR that Microsoft uses the Dinkumware one.
With your above example you're also missing several important pieces of information - the types you describe (Server::StringArray and Server::KeyValueMap) are standard library containers. OK fine, but standard library containers of what? These containers are templates and unless you know the exact types these templates have been instantiated with, you're a little stuck.
Is this DLL intended to be called from C++ at all? The fact that it export a JNI interface suggests that it might not be in the first place. Does it export any other public symbols apart from those that are of the format _Java_...?
Of course if there is no other way in and you must use C++ instead of Java, you might want to look into embedding a JVM into your C++ app and use that to call through to the C++ dll. It's not what I'd call an elegant solution but it might well work.
I don't quite understand the use of C++ standard library data types here. How can Java code provide a std::map argument? Are the arguments you pass in always just "opaque" values you would get as output from a previous call to the library? That's the only way you're going to be able to make it work from code under a different runtime.
Anyway...
When you make a JNI module, you run javah.exe and it generates a header file with declarations like:
JNIEXPORT void JNICALL Java_Native_HelloWorld(JNIEnv *, jobject);
Do you have any such header file for the module?
These symbols are exported as extern "C" if I recall correctly, so if you can get the correct signatures, you should have no issues with name mangling or incompatible memory allocators, etc..
The "#20" at the end of the method signature means that the function is declared "stdcall" and that 20 bytes are put on the stack when the function is called. All these methods should start with a JNIEnv* and a jobject, these will total 8 bytes I believe, on a 32-bit environment, so that leaves 12 bytes of parameters you will need to know in order to generate a correct function prototype.
Once you figure out what the parameters are, you can generate something like this:
typedef void (__stdcall *X)(JNIEnv *, jobject, jint i, jboolean b);
Then, you can cast the result of GetProcAddress to an X and call it from your C++ code.
X x = (X)GetProcAddress(module, "name");
if (x) x(params...);
Unfortunately, what you have doesn't quite look like what I have seen in the past. I am used to having to deal with Java data types from C/C++ code, but it looks like this module is dealing with C++ data types in Java code, so I don't know how relevant any of my experience is. Hopefully this is some help, at least.