javacpp icon indicating copy to clipboard operation
javacpp copied to clipboard

Problem with instantiating templates

Open jpsacha opened this issue 3 years ago • 9 comments

Following preset code attempts to create an instance of a template:

new Info("Spinnaker::GenApi::IEnumerationT<Spinnaker::InterfaceTypeEnum>").pointerTypes("EInterfaceType").define()

Usage of the template in the generated Java code is correctly replaced with EInterfaceType. However, the there is no Java class generated to instantiate the template.

Note that template is in the namespace Spinnaker::GenApi. The template parameter is in the namespace Spinnaker. There is a separate preset for each namespace.

Simplified preset class for GenApi

@Properties(inherit = GenICam.class,
        target = "org.bytedeco.spinnaker.GenApi",
        global = "org.bytedeco.spinnaker.global.GenApi", ...)
public class GenApi implements InfoMapper { ... }

Simplified preset class for Spinnaker

@Properties(inherit = GenApi.class,
        target = "org.bytedeco.spinnaker.Spinnaker",
        global = "org.bytedeco.spinnaker.global.Spinnaker", ...)
public class Spinnaker implements InfoMapper { 
    public void map(InfoMap infoMap) {
        infoMap.put(new Info("Spinnaker::GenApi::IEnumerationT<Spinnaker::InterfaceTypeEnum>")
                           .pointerTypes("EInterfaceType").define())
...
}

Simplified C++ definition of the IEnumerationT:

namespace Spinnaker
{
    namespace GenApi
    {
        template <typename EnumT>
        interface SPINNAKER_API_ABSTRACT IEnumerationT : virtual public IEnumeration, virtual public IEnumReference
        {
          ... 
        }
    }
}

Definition of InterfaceTypeEnum:

namespace Spinnaker
{
	enum InterfaceTypeEnum	/*!< Transport layer type of the interface.*/
	{
		InterfaceType_GigEVision,	/*!< GigE Vision*/
		InterfaceType_CameraLink,	/*!< Camera Link*/
		InterfaceType_CameraLinkHS,	/*!< Camera Link High Speed*/
		InterfaceType_CoaXPress,	/*!< CoaXPress*/
		InterfaceType_USB3Vision,	/*!< USB3 Vision*/
		InterfaceType_Custom,	/*!< Custom transport layer*/
		NUMINTERFACETYPE
	}
...
}

Need to figure out some way to force the instantiation of that template.

jpsacha avatar May 12 '21 21:05 jpsacha

Again, that works fine for me in isolation, this is what I get:

@Name("Spinnaker::GenApi::IEnumerationT<Spinnaker::InterfaceTypeEnum>") @Opaque public class EInterfaceType extends Pointer {
    /** Empty constructor. Calls {@code super((Pointer)null)}. */
    public EInterfaceType() { super((Pointer)null); }
    /** Pointer cast constructor. Invokes {@link Pointer#Pointer(Pointer)}. */
    public EInterfaceType(Pointer p) { super(p); }
}

Please try to figure out a minimal example that fails! Thanks

saudet avatar May 12 '21 23:05 saudet

Here is little different, but a minimal example that may not generate a template, depending on instantiation order.

The template class (simplified), in file BasePtr.h:

#ifndef BASE_PTR_H
#define BASE_PTR_H

namespace MySpace
{
    template <class T, class B = T> class MYAPI_API BasePtr
    {
      public:
        BasePtr(void) throw();

    };
}
#endif

Complete preset:

import org.bytedeco.javacpp.annotation.Platform;
import org.bytedeco.javacpp.annotation.Properties;
import org.bytedeco.javacpp.presets.javacpp;
import org.bytedeco.javacpp.tools.Info;
import org.bytedeco.javacpp.tools.InfoMap;
import org.bytedeco.javacpp.tools.InfoMapper;

@Properties(inherit = javacpp.class,
        target = "org.bytedeco.javacpp_test.Preset_Test",
        global = "org.bytedeco.javacpp_test.global.Preset_Test", value = {
        @Platform(value = {"linux-x86_64", "windows"},
                include = {
                        "BasePtr.h",
                }),
        @Platform(value = "windows",
                includepath = "X:/javacpp_test/include")
})
public class Preset_Test implements InfoMapper {
    public void map(InfoMap infoMap) {
        infoMap
                .put(new Info("MySpace::BasePtr<MySpace::Camera,MySpace::ICameraBase>")
                        .pointerTypes("BasePtr_T_Camera").define())
                .put(new Info("MySpace::BasePtr<MySpace::LoggingEventData>")
                        .pointerTypes("BasePtr_T_LoggingEventData").define())
        ;
    }
}

With that preset the first template BasePtr_T_Camera will be generated, but the second one not. If the order is changed:

                .put(new Info("MySpace::BasePtr<MySpace::LoggingEventData>")
                        .pointerTypes("BasePtr_T_LoggingEventData").define())
                .put(new Info("MySpace::BasePtr<MySpace::Camera,MySpace::ICameraBase>")
                        .pointerTypes("BasePtr_T_Camera").define())

both templates BasePtr_T_Camera and BasePtr_T_LoggingEventData are generated.

jpsacha avatar May 15 '21 02:05 jpsacha

Thanks! Fixed in commit https://github.com/bytedeco/javacpp/commit/a105765960584a2205cc21d06c2123f19a3443dd.

saudet avatar May 17 '21 02:05 saudet

Commit a105765 fixed one issue (https://github.com/bytedeco/javacpp/issues/478#issuecomment-841583087) There is still issue reported originally. I tried to minimize and reduced to two simple presets and a couple of includes. include.zip presets.zip This is a simplified setup described at the very top. Hope this helps

jpsacha avatar May 17 '21 23:05 jpsacha

The definitions of SPINNAKER_API_ABSTRACT and SPINNAKER_API are missing, so that's probably not going to work anyway. Do you still have issues when removing all traces of those?

saudet avatar May 17 '21 23:05 saudet

Removing SPINNAKER_API_ABSTRACT and SPINNAKER_API did not make difference to template generation (not generated). Corrected includes are attached include.zip

jpsacha avatar May 18 '21 00:05 jpsacha

I see, that's "normal" in the sense that the Spinnaker::GenApi::IEnumerationT template isn't available in the header files included for the Spinnaker class. Until that gets fixed somehow, you'll need to copy those header files from the GenApi class.

saudet avatar May 19 '21 01:05 saudet

Is everything alright? Is it working now?

saudet avatar May 25 '21 03:05 saudet

Nothing changed here. I may not have a chance to get to it for a couple of days. I am also running in a couple of other unrelated issues in wrapping Spinnaker C++ API, like dealing with pointer wrapper classes (I will post separately when I have them in a simple format)

jpsacha avatar May 25 '21 04:05 jpsacha