Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
egolearner opened this issue May 27, 2021 · 14 comments
Closed

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

egolearner opened this issue May 27, 2021 · 14 comments

Comments

@egolearner
Copy link

egolearner commented May 27, 2021

    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.

@saudet
Copy link
Member

saudet commented May 27, 2021

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

@egolearner
Copy link
Author

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

@saudet
Copy link
Member

saudet commented May 28, 2021

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

@egolearner
Copy link
Author

Remove && works. Thanks a lot @saudet

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

@saudet saudet reopened this May 28, 2021
@saudet
Copy link
Member

saudet commented May 10, 2022

BTW, I've added support for std::function as a "basic container" in commit bytedeco/javacpp@587ed7a, so this should work now. Please give it a try with the snapshots: http://bytedeco.org/builds/

@egolearner
Copy link
Author

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]

@saudet
Copy link
Member

saudet commented May 12, 2022

@saudet
Copy link
Member

saudet commented May 14, 2022

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.

@egolearner
Copy link
Author

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)

@saudet
Copy link
Member

saudet commented May 18, 2022 via email

@egolearner
Copy link
Author

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

@saudet
Copy link
Member

saudet commented May 18, 2022 via email

@egolearner
Copy link
Author

It works.
I appreciate your effort @saudet

@saudet
Copy link
Member

saudet commented Nov 3, 2022

This has now been released with JavaCPP 1.5.8. Enjoy!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants