javacpp-presets icon indicating copy to clipboard operation
javacpp-presets copied to clipboard

How to deal with template taking std::function as arguments?

Open egolearner opened this issue 4 years ago • 13 comments

    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.

egolearner avatar May 27 '21 09:05 egolearner

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

saudet avatar May 27 '21 13:05 saudet

        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);"));

egolearner avatar May 28 '21 02:05 egolearner

Try without the &&, it's not being processed as part of type signature, although it probably should...

saudet avatar May 28 '21 03:05 saudet

Remove && works. Thanks a lot @saudet

        infoMap.put(new Info("SomeClass::set_filter<std::function<bool(uint64_t)> >").javaNames("set_filter"));

egolearner avatar May 28 '21 03:05 egolearner

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/

saudet avatar May 10 '22 22:05 saudet

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]

egolearner avatar May 12 '22 13:05 egolearner

It's clearly here: https://oss.sonatype.org/content/repositories/snapshots/org/bytedeco/javacpp/1.5.8-SNAPSHOT/

saudet avatar May 12 '22 13:05 saudet

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.

saudet avatar May 14 '22 11:05 saudet

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)

egolearner avatar May 18 '22 12:05 egolearner

You'll need to use another name than "FunctionPointer".

saudet avatar May 18 '22 12:05 saudet

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);

egolearner avatar May 18 '22 12:05 egolearner

Info.define needs to be set: https://github.com/bytedeco/javacpp/wiki/Mapping-Recipes#defining-wrappers-for-basic-c-containers

saudet avatar May 18 '22 12:05 saudet

It works. I appreciate your effort @saudet

egolearner avatar May 18 '22 15:05 egolearner

This has now been released with JavaCPP 1.5.8. Enjoy!

saudet avatar Nov 03 '22 04:11 saudet