JavaCPP fails at function disambiguation - java

I am implementing a Java wrapper for a C++ project using JavaCPP. I have defined mappings for all custom types, but I'm struggling with a call to the std::sort_heap() function that takes a function as an argument.
This is the function call in the C++ code:
std::sort_heap(heap.begin(), heap.end(), comparePairs);
comparePairs is declared like this in this file:
bool comparePairs(
const std::pair<real, int32_t>& l,
const std::pair<real, int32_t>& r) {
return l.first > r.first;
}
When I try to run this with JavaCPP (using the JavaCPP Maven plugin), I get this error:
error: no matching function for call to ‘pop_heap(std::vector<std::pair<float, int> >::iterator, std::vector<std::pair<float, int> >::iterator, <unresolved overloaded function type>)’
std::pop_heap(heap.begin(), heap.end(), comparePairs);
^
Update: the problem seems to be due to the fact that another compairePairs() with a slightly different signature function is declared in another file. The C++ compiler disambiguates them fine, considering that each compairePairs() function is called only within the same file. However, JavaCPP seems to fail at that disambiguation somehow.
This is how the other type mappings are declared:
import org.bytedeco.javacpp.tools.Info;
import org.bytedeco.javacpp.tools.InfoMap;
import org.bytedeco.javacpp.tools.InfoMapper;
[...]
#Properties(value = #Platform(include = {[...]}), target = "[...]")
public class Wrapper implements InfoMapper {
public void map(InfoMap infoMap) {
infoMap.put(new Info("std::vector<std::string>").pointerTypes("StringVector").define())
// more put calls here
;
}
}
Question is thus: why does JavaCPP fail to disambiguate overloaded functions, and how can I fix it?
Note: the C++ code is a third party project, so changing the C++ code is not an option.
Update: the issues appears to be due to the compairPairs() function being declared twice in the C++ code (in two different files), with different signatures.

As described in the comment, wrapping the function call to comparePairs() into a lambda function resolves the issue.
See https://github.com/facebookresearch/fastText/pull/936/commits/cda295f1b5851df0a26a6ac2ab04230fb864a89d

Related

using in C# vs. import in Java

I am coming from Java and C++ background. However, I am doing a C# application at the moment and one thing made me confused.
In Java when I import a package, it means I can access the classes that are placed in that package. For example, here I imported the ArrayList class from package java.util.
import java.util.ArrayList;
class ArrayListUtilization {
public static void main(String[] args) {
ArrayList<Integer> myList = new ArrayList<>(3);
myList.add(3);
myList.add(2);
myList.add(1);
System.out.println(myList);
}
}
Recently I had a problem in my c-sharp app, that I asked here. The funny part in my point of view is, when I added the following snippet of code:
var accountDbContext = services.GetRequiredService<AccountDbContext>();
accountDbContext.Database.EnsureCreated();
var accountDbCreator = accountDbContext.GetService<IRelationalDatabaseCreator>();
accountDbCreator.CreateTables();
I saw an error as following:
Error CS1929 'AccountDbContext' does not contain a definition for
'GetService' and the best extension method overload
'ServiceProviderServiceExtensions.GetService(IServiceProvider)'
requires a receiver of type 'IServiceProvider'
and from the error text, I understood accountDbContext object does not have GetService function. But when I press on show potential fixes, then it suggests me to add a using statement.
And it was the real fix. However, my question is what is the effect of this using statement on my object? The object is an instantiation of its class. How can adding a using statement effect on my object and add a function to it?
Note that what you are actually calling an extension method here:
accountDbContext.GetService<IRelationalDatabaseCreator>();
accountDbContext does not have a method called GetService. GetService is declared in AccessorExtensions, and the above line is just syntactic sugar for:
AccessorExtensions.GetService<IRelationalDatabaseCreator>(accountDbContext);
Now it should make sense that you need to add a using directive for the class in which the extension method is declared, in order to access the extension method.

Java ME: javax.microedition classes appear unimplemented

I'm developing a Java ME project in Intellij. When I try to call a function from the javax.microedition package, all functions simply return null. After inspection, these functions exist but contain no substance (are unimplemented). For example, the javax.microedition.io.connector class function .open(String var) appears this way and always returns null:
public static Connection open(String var0) throws IOException {
return null;
}
This function does not match the documentation provided by Oracle and according to the documentation Connector is not an abstract class. All other functions I inspected seem to be implemented the same way. Did I miss a step in setting up the Java ME SDK? Am I missing something?
Additionally this is the code I try to run but returns null:
ServerSocketConnection server = (ServerSocketConnection) Connector.open("socket://:4040");
These are called stub classes. They only contain method signatures and default return values. You can use them to compile your code without problems.
When you run your app on an emulator (or on an actual device) these classes will have a proper implementation and behave as expected.

Android app cannot install

While developing an app in AIDE for Android I have come across this error. The app would compile successfully but wouldn't install, reporting this error:
Could not run the App directly as root. Consider disabling direct running in the settings.
WARNING: linker: app_process has text relocations. This is wasting memory and is a security risk. Please fix.
pkg: /storage/sdcard/AppProjects/MyProgram/bin/MyProgram.apk
Failure [INSTALL_FAILED_DEXOPT]
exit with 0
I researched what could cause this and mainly came across reasons like "certificate error, try resigning the package" and "setting a permission twice in the manifest" and other stuff, none of which have worked.
Your problem: Java thinks you define two methods with the same signature.
Java method signature definition: https://docs.oracle.com/javase/tutorial/java/javaOO/methods.html
method declarations have six components, in order:
1.Modifiers—such as public, private, and others you will learn about later.
2.The return type—the data type of the value returned by the method, or void if the method does not return a value.
3.The method name—the rules for field names apply to method names as well, but the convention is a little different.
4.The parameter list in parenthesis—a comma-delimited list of input parameters, preceded by their data types, enclosed by parentheses, ().
If there are no parameters, you must use empty parentheses.
An exception list—to be discussed later.
The method body, enclosed between braces—the method's code, including the declaration of local variables, goes here.
As you can see above, the specification of generic classes is NOT part of the java method signature. Therefore java detects two add-methods with the same signature.
I found where the problem resides. It was in some code which looked very much like this:
public class Builder<T extends Base> {
private final List<Def1> subDefs1 = new ArrayList<>();
private final List<Def2> subDefs2 = new ArrayList<>();
public Builder<T> add(final Collection<Def1> ds) {
subDefs1.addAll(ds);
return this;
}
public Builder<T> add(final Collection<Def2> ds) {
subDefs2.addAll(ds);
return this;
}
}
interface Base {}
final class Def1 implements Base {}
final class Def2 implements Base {}
I had these add methods, which both take a Collection of some kind. The problem must be something to do with Java's lacklustre generics and the dexing process, I guess...

Call native JNI DLL from C#

I have a native DLL abc.dll (without source code) that was originally used in a JNI call in Java like this:
public class ABC_Proxy
{
private native void callABC(String parameter);
public ABC_Proxy()
{
System.loadLibrary("abc");
}
public void Start(String paramater)
{
callABC(paramater);
}
}
Now I am trying to execute the same function in C#. Using dumpbin I found the correct full entry point, and this is what I came up with so far:
class Abc
{
[DllImport("abc.dll", EntryPoint="_Java_my_namespace_abc_1Proxy_callABC#12")]
private static extern void CallAbc(string parameter);
public void Start(string parameter)
{
CallAbc("test");
}
}
I can see that CallAbc is executed and does something (it creates a file) but then it throws an AccessViolationException, presumably when it tries to access the parameter.
The PureDLLHelper suggests that the function has 3 parameters, and after reading this JNI tutorial I have the feeling that I also need to pass the parameters JNIEnv*, jobject to simulate a JNI call. But from here on I'm lost...
Any idea? Is it even possible what I'm trying to achieve?
Edit: I just want to mention this forum post that has a good explanation of the problems involved and how they could by solved. However, the solutions are based on Xamarin.Android to bridge the C#/Java gap and get hold of the JNIEnv, which is not really an option for me.
Its not going to work, simple as that. The JNI DLL is designed and built to be loaded by the JVM. You will not be able to provide the pointers to the env or jvm that are required to call any of the functions contained in that library. Your only option would be to create a second DLL that creates a new instance of the JVM that then calls the DLL you have, but if you are calling Java from .Net, you may as well keep it all in Java.

Java or any other language: Which method/class invoked mine?

I would like to write a code internal to my method that print which method/class has invoked it.
(My assumption is that I can't change anything but my method..)
How about other programming languages?
EDIT: Thanks guys, how about JavaScript? python? C++?
This is specific to Java.
You can use Thread.currentThread().getStackTrace(). This will return an array of StackTraceElements.
The 2nd element in the array will be the calling method.
Example:
public void methodThatPrintsCaller() {
StackTraceElement elem = Thread.currentThread.getStackTrace()[2];
System.out.println(elem);
// rest of you code
}
If all you want to do is print out the stack trace and go hunting for the class, use
Thread.dumpStack();
See the API doc.
Justin has the general case down; I wanted to mention two special cases demonstrated by this snippit:
import java.util.Comparator;
public class WhoCalledMe {
public static void main(String[] args) {
((Comparator)(new SomeReifiedGeneric())).compare(null, null);
new WhoCalledMe().new SomeInnerClass().someInnerMethod();
}
public static StackTraceElement getCaller() {
//since it's a library function we use 3 instead of 2 to ignore ourself
return Thread.currentThread().getStackTrace()[3];
}
private void somePrivateMethod() {
System.out.println("somePrivateMethod() called by: " + WhoCalledMe.getCaller());
}
private class SomeInnerClass {
public void someInnerMethod() {
somePrivateMethod();
}
}
}
class SomeReifiedGeneric implements Comparator<SomeReifiedGeneric> {
public int compare(SomeReifiedGeneric o1, SomeReifiedGeneric o2) {
System.out.println("SomeRefiedGeneric.compare() called by: " + WhoCalledMe.getCaller());
return 0;
}
}
This prints:
SomeRefiedGeneric.compare() called by: SomeReifiedGeneric.compare(WhoCalledMe.java:1)
somePrivateMethod() called by: WhoCalledMe.access$0(WhoCalledMe.java:14)
Even though the first is called "directly" from main() and the second from SomeInnerClass.someInnerMethod(). These are two cases where there is a transparent call made in between the two methods.
In the first case, this is because we are calling the bridge method to a generic method, added by the compiler to ensure SomeReifiedGeneric can be used as a raw type.
In the second case, it is because we are calling a private member of WhoCalledMe from an inner class. To accomplish this, the compiler adds a synthetic method as a go-between to override the visibility problems.
the sequence of method calls is located in stack. this is how you get the stack: Get current stack trace in Java then get previous item.
Since you asked about other languages, Tcl gives you a command (info level) that lets you examine the call stack. For example, [info level -1] returns the caller of the current procedure, as well as the arguments used to call the current procedure.
In Python you use the inspect module.
Getting the function's name and file name is easy, as you see in the example below.
Getting the function itself is more work. I think you could use the __import__ function to import the caller's module. However you must somehow convert the filename to a valid module name.
import inspect
def find_caller():
caller_frame = inspect.currentframe().f_back
print "Called by function:", caller_frame.f_code.co_name
print "In file :", caller_frame.f_code.co_filename
#Alternative, probably more portable way
#print inspect.getframeinfo(caller_frame)
def foo():
find_caller()
foo()
Yes, it is possible.
Have a look at Thread.getStackTrace()
In Python, you should use the traceback or inspect modules. These will modules will shield you from the implementation details of the interpreter, which can differ even today (e.g. IronPython, Jython) and may change even more in the future. The way these modules do it under the standard Python interpreter today, however, is with sys._getframe(). In particular, sys._getframe(1).f_code.co_name provides the information you want.

Categories