Hijacking plugin type factory creation

For reasons, I want to write a SdfFileFormat plugin in C. This means creating a trampoline class that takes a bunch of function pointers in its constructor (essentially the virtual function table).

From perusing the code, I can’t see an easy way to make this work, since the factory New() method and factory construction itself are done entirely through default constructors with no way to pass runtime arguments.

I’m wondering if there’s any other method of creating types or SdfFileFormat-derived instances that I’m not aware of that I could use to do this.

I’m unaware of a way to do that dynamically. But, where would the function pointers come from in the first place? If you are able to provide C++ code that marshals up the pointers to pass along to a (not-supported) ctor for SdfFileFormat, could you not instead create a C++ definition whose thin body just calls out to the C functions?

The function pointers would be passed via a C API to the trampoline class, in the trampoline constructor. Consider:

// In OpenUSD, imagine this is SdfFileFormat, I've simplified it for clarity's sake
class FileFormat {
public:
    virtual bool Read(char const* path) const = 0;
};
// in OpenUSD C Wrapper exposed as a C dynamic library
typedef bool (FileFormat_Read*)(char const* path);

class FileFormatTrampoline : public FileFormat {
    FileFormat_Read _fn_read;
public:
    // constructor stashes the provided function pointer to "construct its virtual function table"
    FileFormatTrampoline(FileFormat_Read fn_read) : _fn_read(fn_read){}

    ~FileFormatTrampoline(){}

    virtual bool Read(char const* path) {
        return _fn_read(path);
    }
};

extern "C" void FileFormatTrampoline_ctor(FileFormatRead fn_read, FileFormatTrampoline** result) {
    *result = new FileFormatTrampoline(fn_read);
}

extern "C" void FileFormatTrampoline_dtor(FileFormatTrampoline* _this) {
    delete _this;
}
// in hypothetical C OpenUSD Plugin, which links against the C library
bool ReadMyFileFormat(char const* path) {
    // read my custom file format and use the OpenUSD C API to create the Prims etc...
}

// need some way of giving a custom creator (and destroyer) function to USD for constructing the type
FileFormat* HypotheticalFileFormatCreator() {
    FileFormat* format;
    FileFormatTrampoline_ctor(ReadMyFileFormat, &format);
    return format;
}

void HypotheticalFileFormatDestroyer(FileFormat* format) {
    FileFormatTrampoline_dtor(format);
}

In this way I could write plugins in C (and any language you want to bind to C). The trick is that the function pointers must be passed to the Trampoline class at runtime, but the plugin mechanism needs everything defined at compile time AFAICT.

If there was some way of passing HypotheticalFileFormatCreator() and HypotheticalFileFormatDestroyer() to the TfType system to be used instead of the existing factory mechanism then I think this would work.