Replies: 1 comment 3 replies
-
Hi @JaXt0r, With this, I am especially looking for feedback on the getter-style functions (like As for the VM, I have some ideas on how to properly integrate it with C. There are some problems to work out though still so here are my ideas. Parsing scripts and creating a VM from them as well as accessing its symbols and performing code execution will be very simple (even though a lot of work) to implement. The tricky part comes with all the template magic I've created to provide a type-safe implementation including runtime checks for creating instances, calling functions and registering externals. There are two ways I can think of to make this work in C. 1. Requiring manual stack push/pop for return values and function parameters This implementation would not be very ergonomic to use since any registered external would have to manually pop its parameters off the VM's stack and push its return value onto it. Function calls could probably be implemented using a typedef void(*PxVMExternal)(PxVM*);
PxVM* px_vm_create(PxScript*);
void px_vm_destroy(PxVM* vm);
void px_vm_register_external(PxVM* vm, PxVMExternal* ext);
void px_vm_call_function(PxVM* vm, char const* func, ...);
void px_vm_call_function_by_index(PxVM* vm, uint32_t index, char const* signature, ...);
// I am unsure about this:
void px_vm_init_instance(PxVM* vm, char const* name, void* instance); One would use this API like so: void my_external(PxVM* vm) {
char const* name = px_vm_pop_string(vm);
// ...
}
int main() {
PxScript* script;
PxVM* vm = px_vm_create(script);
// Registering an external:
px_vm_register_external(vm, "PlayVideo", my_external);
// Calling a function by name:
void* my_instance /* from somewhere*/;
int rv /* will be the return valuie of MyScriptFunc */;
px_vm_call_function(vm, "MyScriptFunc(Iis)i", my_instance, 100, "my string", &rv);
// Calling a function by index:
void* my_instance /* from somewhere*/;
int rv /* will be the return valuie of the function */;
px_vm_call_function_by_index(vm, 0x1234, "(Iis)i", my_instance, 100, "my string", &rv);
// ... and I'm not sure about initializing instances yet.
px_vm_destroy(vm);
return 0;
} 2. Determining external parameters and return values from a signature parameter This works basically the same as 1. but here we also use a typedef void(*PxVMExternal)(PxVM*, ...);
void px_vm_register_external(PxVM* vm, char const* signature, PxVMExternal* ext); and you would use it like this: void my_external(PxVM* vm, char const* par0) {
// ...
}
int main() {
PxScript* script;
PxVM* vm = px_vm_create(script);
// Registering an external:
px_vm_register_external(vm, "PlayVideo(s)v", my_external);
// And the rest like in 1.
px_vm_destroy(vm);
return 0;
} As you can probably tell, the second way of registering externals is a lot simpler to implement for a potential API-consumer since the function parameters don't have to be popped off the VM's stack manually. It also allows for better detection of invalid function signatures at runtime since the expected signature is already provided. Again, I am not sure if something like this is even possible in C. The first way of writing this API is much easier to implement for me though since I already know how to do it. It also has the advantage of being very flexible with how externals can be implemented but it comes at the cost of ergonomics and less straightforward function signature checks at runtime, making it less safe as well. Do you have any other ideas on how to approach this which would be helpful to you specifically, maybe? I'm happy about any feedback or ideas you might have :) |
Beta Was this translation helpful? Give feedback.
-
Hi lmichaelis,
thank you for your wonderful G1/G2 parser library! I'm currently developing a rebuild of Gothic in VR with Unity heavily relying on your parser library. The thing is: As Unity leverages C#, we can't just consume your C++ library, but instead need to leverage PInvoke with C-style via shared libraries (DLLs). Therefore we need to bridge your project.
I wanted to check with you if:
A few hints about what needs to be changed if exposing your API as C functions:
someString.c_str()
)someSharedPtr.data()
)For sure, there will be more. Nevertheless, you're solution is really neat and I overcame every C++->C demands as of now.
Feel free to have a look at my implementation for further discussions:
https://github.com/GothicVRProject/phoenix-csharp-bridge
Best
JaXt0r
Beta Was this translation helpful? Give feedback.
All reactions