javacpp-presets
javacpp-presets copied to clipboard
How to deal with template taking std::function as arguments?
template <typename T>
void set_filter(T &&func) {
// ...
}
T's receiver is std::function<bool(uint64_t)>.
We tried to add the following mapping info
infoMap.put(new Info("std::function<bool(uint64_t)>").pointerTypes("FilterFunction"));
infoMap.put(new Info("SomeClass::set_filter<std::function<bool(uint64_t)> >&&").javaNames("setFiler"));
mvn install works but the function is omitted from generated java file.
There isn't a way to map that as a "basic container", yet, but if it's just for an argument, we can map it using a FunctionPointer, as is done in many presets, for example, here:
https://github.com/bytedeco/javacpp-presets/blob/master/pytorch/src/main/java/org/bytedeco/pytorch/presets/torch.java#L995
infoMap.put(new Info("std::function<bool(uint64_t)>").pointerTypes("FilterFunction"));
public static class FilterFunction extends FunctionPointer {
static { Loader.load(); }
/** Pointer cast constructor. Invokes {@link Pointer#Pointer(Pointer)}. */
public FilterFunction(Pointer p) { super(p); }
protected FilterFunction() { allocate(); }
private native void allocate();
public native boolean call(@Cast("uint64_t") long key);
}
Hi @saudet, I added FilterFunction definition according to your comments. It worked if I add another non template function.
void set_filter2 (std::function<bool(uint64_t)> &&func) {
filter_ = std::move(func);
}
However, the original function is a template function. I still cannot get it work. I have tried adding the following mapping info.
// infoMap.put(new Info("SomeClass::set_filter<std::function<bool(uint64_t)> >&&").javaNames("set_filter"));
// infoMap.put(new Info("SomeClass::set_filter<std::function<bool(uint64_t)> >&&")
// .javaText("public native void set_filter(@ByVal FilterFunction func);"));
Try without the &&, it's not being processed as part of type signature, although it probably should...
Remove && works. Thanks a lot @saudet
infoMap.put(new Info("SomeClass::set_filter<std::function<bool(uint64_t)> >").javaNames("set_filter"));
BTW, I've added support for std::function as a "basic container" in commit https://github.com/bytedeco/javacpp/commit/587ed7a4e704927eb9238f0fae80ff9a5d546ed7, so this should work now. Please give it a try with the snapshots: http://bytedeco.org/builds/
Got stuck with the following mvn error. Help needed.
[ERROR] Plugin org.bytedeco:javacpp:javacpp-1.5.8-SNAPSHOT or one of its dependencies could not be resolved: Could not find artifact org.bytedeco:javacpp:jar:javacpp-1.5.8-SNAPSHOT in sonatype-nexus-snapshots (https://oss.sonatype.org/content/repositories/snapshots) -> [Help 1]
It's clearly here: https://oss.sonatype.org/content/repositories/snapshots/org/bytedeco/javacpp/1.5.8-SNAPSHOT/
In any case, it's easy to build from source, so just do that if you're not able to fix whatever networking issue you're having.
got mvn problem solved.
Am I supposed to add the following mapping info?
infoMap.put(new Info("std::function<bool(uint64_t)>").pointerTypes("FunctionPointer"));
Parsing phase succeeds with the following warning
[WARNING] Method "public native void com.mycompany.MyClass.set_filter(org.bytedeco.javacpp.FunctionPointer)" has an abstract FunctionPointer parameter, but a concrete subclass is required. Compilation will most likely fail.
And building fails with the following message
Execution javacpp-compiler of goal org.bytedeco:javacpp:1.5.8-SNAPSHOT:build failed: 1
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:498)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
Caused by: org.apache.maven.plugin.PluginExecutionException: Execution javacpp-compiler of goal org.bytedeco:javacpp:1.5.8-SNAPSHOT:build failed: 1
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:148)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:498)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 1
at org.bytedeco.javacpp.tools.Generator.classes (Generator.java:1550)
at org.bytedeco.javacpp.tools.Generator.generate (Generator.java:246)
at org.bytedeco.javacpp.tools.Builder.generateAndCompile (Builder.java:580)
at org.bytedeco.javacpp.tools.Builder.build (Builder.java:1167)
at org.bytedeco.javacpp.tools.BuildMojo.execute (BuildMojo.java:417)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:498)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
You'll need to use another name than "FunctionPointer".
You'll need to use another name than "FunctionPointer".
Still not work.
infoMap.put(new Info("std::function<bool(uint64_t)>").pointerTypes("MyFilterFunction"));
cannot find symbol
[ERROR] symbol: class MyFilterFunction
48: public native void set(@ByRef(true) MyFilterFunction func);
Info.define needs to be set: https://github.com/bytedeco/javacpp/wiki/Mapping-Recipes#defining-wrappers-for-basic-c-containers
It works. I appreciate your effort @saudet
This has now been released with JavaCPP 1.5.8. Enjoy!