So first I load in a DLL I need
local ffi = require("ffi")
local theDLL = ffi.load("thisDLL")
in the ffi cdef I have two different kinds of structs
ffi.cdef [[
typedef struct StructSession StructSession;
typedef struct {
/*
* begin_proj callback
*/
bool (__cdecl *begin_proj)(char *proj);
/*
* save_proj_state
*/
bool (__cdecl *save_proj_state)(unsigned char **buffer, int *len);
} StructCallbacks;
I also have this function in the cdef
__declspec(dllexport) int __cdecl start_session(StructSession **session,
StructCallbacks *cb);
Now I would like to call this function
print(theDLL.start_session(a,b))
vars a and b are obviously placeholders, the question is how can I pass the structs the function needs? And say we get StructSession working, is making a callback to a function WITHIN LuaJIT even going to be possible for StructCallbacks?
Creating the StructCallbacks is easy; you can create it with ffi.new and create FFI callbacks for the fields (see the FFI semantics for information on callbacks).
Creating the StructSession is trickier since it's an opaque type, but it's not much different from how you would do it in C.
Here is how you would create one in C:
StructSession* S = NULL;
start_session(*S, foo);
Notice how you are not directly allocating a StructSession. Instead, you allocate a pointer to one, and let start_session allocate the actual struct.
So we now translate this to LuaJIT code:
local S = ffi.new("StructSession*")
lib.start_session(getPointer(S), foo) -- getPointer should take the pointer of S, but...
...the FFI doesn't provide any way to take the pointer of an object (This is intentional; it allows for optimizations).
So how do we get a pointer to a StructSession? Well, recall that arrays are convertible to pointers, and we can access those through the FFI. So we instead create a single-slot array of pointers and pass that to start_session:
local S_slot = ffi.new("StructSession*[1]")
lib.start_session(S_slot, foo)
local S = S_slot[0]
And now you have a StructSession object.
Related
My purpose is to call some C function from my C++ code and pass some C++ objects.
In fact I am using a integration routine from the GSL libray(written in C), see this link,
My code snippet:
// main.cpp
#include <stdio.h>
#include <gsl/gsl_integration.h>
#include <myclass.h>
/* my test function. */
double testfunction ( double x , void *param ) {
myclass *bar=static_cast<myclass*>(param);
/*** do something with x and bar***/
return val;
}
int main ( int argc , char *argv[] ) {
gsl_function F; // defined in GSL: double (* function) (double x, void * params)
/* initialize.*/
gsl_integration_cquad_workspace *ws =
gsl_integration_cquad_workspace_alloc( 200 ) ;
/* Prepare test function. */
myclass foo{}; // call myclass constructor
F.function = &testfunction;
F.params = &foo;
/* Call the routine. */
gsl_integration_cquad( &F, 0.0,1.0,1.0e-10,1.0e-10,ws, &res,&abserr,&neval);
/* Free the workspace. */
gsl_integration_cquad_workspace_free( ws );
return 0;
}
In my case, direct calling gsl_integration_cquad seems OK, provided the header includes sth like "ifdef __cplusplus", my concern is about the callback F,originally defined in C, am I allowed to pass the testfunction and also the C++ foo object in this way ? .
or is there any better way to do this kind of stuff, maybe overloading and use a functor?
P.S. Am I allowed to do exeption handling within the callback function? (use try catch inside "testfunction"). It works in my case but not sure if it's legal.
I'm not familiar with the library in question, but in general,
when passing a pointer to a callback and a void* to
a C routine, which will call the callback back with the void*,
there are two things you need to do to make it safe:
The function whose address you pass must be declared extern "C".
You'll get away with not doing this with a lot of compilers, but
it isn't legal, and a good compiler will complain.
The type you convert to the void* must be exactly the same
type as the type you cast it back to in the callback. The
classic error is to pass something like new Derived to the
C function, and cast it back to Base* in the callback. The
round trip Derived*→void*→Base* is undefined
behavior. It will work some of the time, but at other times, it
may crash, or cause any number of other problems.
And as cdhowie pointed out in a comment, you don't want to
allow exceptions to propagate accross the C code. Again, it
might work. But it might not.
For the exact example you posted, the only thing you need to do
is to declare testfunction as extern "C", and you're all
right. If you later start working with polymorphic objects,
however, beware of the second point.
You can use
myclass *bar=static_cast<myclass*>(param);
with void*.
If you meant something like transporting a c++ class pointer through a c callback's void* pointer, yes it's safe to do a static_cast<>.
There's no kind of losing c++ specific attributes of this class pointer, when passed through c code. Though passing a derived class pointer, and static casting back to the base class, won't work properly as #James Kanze pointed out.
The void* will likely just be passed trough by the C library without looking at the pointed-to data, so it's not a problem if this contains a C++ class. As log as you cast the void* to the correctly there shouldn't be any problems.
To make sure the callback function itself is compatible, you can declare it as extern "C". Additionally you should make sure that no exceptions are thrown from the callback function, since the C code calling the callback won't expect those.
All together I would split up the code into one function that does the real work and another function that is used as the callback and handles the interface with the C library, for example like this:
#include <math.h>
double testfunction ( double x ,myclass *param ) {
/*** do something with x and bar***/
return val;
}
extern "C" double testfunction_callback ( double x , void *param ) {
try {
myclass *bar=reinterpret_cast<myclass*>(param);
return testfunction(x, bar);
}
catch(...) {
std::cerr << "Noooo..." << std::endl;
return NAN;
}
}
is there a possibility or a workaround to pass a member function to the Windows API function QueueUserAPC()?
Okay, I could pass a static member function.
But then I won't have full access to local member variables...
So is there a possibility to combine both, passing as member function and full access to non-static member variables?
I tried to work out a solution related to this but without any success yet.
Hopefully someone got an idea to solve this.
This is a kind of standard pattern to use when having C-style callbacks call your C++ functions.
You create a free function (or static member) that forwards the call ...
VOID CALLBACK ForwardTo_MyClass_func( _In_ ULONG_PTR dwParam )
{
auto* p = (MyClass*)dwParam;
p->func();
}
... and you then set it up by passing the instance pointer as the third parameter to QueueUserAPC:
QueueUserAPC( ForwardToMyClass_func, hThread, (ULONG_PTR)pMyClass );
If you need further arguments, you will have to create some kind of structure to hold both the instance pointer and the arguments.
The answer is no.
Windows API has a C interface, and therefor cannot handle name mangled signatures, such as C++ member functions. The function you pass must be a C style free function.
By the way, nesting it in a namespace is acceptable, if less scalable:
namespace apc_stuff
{
static MyStruct some_static_data;
static void __stdcall MyApcFunc(ULONG_PTR data); // PAPCFUNC
};
using namespace apc_stuff;
MyClass::DoSomething(...)
{
auto my_data = new MyData(...);
auto data = reinterpret_cast<ULONG_PTR>(my_data);
QueueUserAPC(MyApcFunc, hThread, data)
}
/*static*/ void __stdcall apc_stuff::MyApcFunc(ULONG_PTR data)
{
auto my_data = reinterpret_cast<MyData *>(data);
//
// use my_data
// use some_static_data
//
}
I am writing an adapter to combine two APIs (one in C and another in C++).
If a function is called on the one API I need to pass the callers ID and the function's arguments to an adapter and call the according function with this information passed.
Now aparently they can not be mapped directly as one interface requires C++ compilation and the name mangling would screw the other so that is why I am using a set of adapters in the first place.
As the number of arguments varies, I looked up variadic functions and found the idea pretty useful, however I am operating on POD only and have to deal with structs, enums and a lot of different arguments per call, which might need to be put back into a struct before feeding it to the target function.
Every example I stumbled upon was far simpler and involved mostly arithmetic operations like summing stuff up , finding largest numbers or printing. Mostly done with for loops on the var_list.
Maybe I got stuck on the idea and it won't work at all, but I am just curious...
Say I wanted to assign the arguments from the list to my target functions parameters (the order of the arguments passed is the correct one), what would be a good way?
BOOL Some_Function(
/* in */ CallerId *pObjectId,
/* in */ someDataType argument1 )
{
BOOL ret = Adapter_Call(pFunction, pObjectId, argument1);
return ret;
}
and so once I made it to the right adapter I want to do
BOOL Adapter_Call(*pFunction, *pObjectId, argument1, ...)
{
va_list args;
va_start(args, argument1);
/*go over list and do `var_list[i] = pFunctionArgList[i]` which is
of whatever type so I can use it as input for my function */
va_end(args);
pObjectId.pFunction(arg1,...,argn);
}
Can I access the input parameters of a function to perform assignments like this?
Has anyone done something like this before? Is there a conceptual mistake in my thinking?
All I found on the net was this, http://www.drdobbs.com/cpp/extracting-function-parameter-and-return/240000586but due to the use of templates I am not sure if it wouldn't create another problem and so in the end implementing an adapter for each and every single functioncall may be simpler to do.
A SO search only returned this: Dynamic function calls at runtime (va_list)
First, you should heed Kerrek's advice about extern "C". This is C++'s mechanism for giving an identifier C linkage, meaning that the name won't be mangled by the C++ compiler.
Sometimes, and adapter still needs to be written for a C++ interface, because it manipulates objects that do not map to a C POD. So, the adapter gives the C interface a POD or opaque pointer type to manipulate, but the implementation of that interface converts that into an C++ object or reference and then calls the C++ interface. For example, suppose you wanted to provide a C interface for C++ std::map<int, void *>, you would have a common header file in C and C++ that would contain:
#ifdef __cplusplus
extern "C" {
#endif
struct c_map_int_ptr;
// ...
// return -1 on failure, otherwise 0, and *data is populated with result
int c_map_int_ptr_find (struct c_map_int_ptr *, int key, void **data);
#ifdef __cplusplus
}
#endif
Then, the C++ code could implement the function like:
typedef std::map<int, void *> map_int_ptr;
int c_map_int_ptr_find (struct c_map_int_ptr *cmap, int key, void **data) {
map_int_ptr &map = *static_cast<map_int_ptr *>(cmap);
map_int_ptr::iterator i = map.find(key);
if (i != map.end()) {
*data = i->second;
return 0;
}
return -1;
}
Thus, there is no need to pass the arguments passed via the C interface through a variable argument adapter. And so, there is no need for the C++ code to tease out the arguments from a variable argument list. The C code calls directly into the C++ code, which knows what to do with the arguments.
I suppose if you are trying to implement some kind of automated C adapter code generator by parsing C++ code, you could think that using variable arguments would provide a regular mechanism to communicate arguments between the generated C code interface and the generated C++ adapter code that would call the original C++ interface. For such a scenario, the code for the above example would look something like this:
// C interface
typedef struct c_map_int_ptr c_map_int_ptr;
typedef struct c_map_int_ptr_iterator c_map_int_ptr_iterator;
//...
c_map_int_ptr_iterator c_map_int_ptr_find (c_map_int_ptr *map, int key) {
c_map_int_ptr_iterator result;
cpp_map_int_ptr_adapter(__func__, map, key, &result);
return result;
}
// C++ code:
struct cpp_adapter {
virtual ~cpp_adapter () {}
virtual void execute (va_list) {}
};
void cpp_map_int_ptr_adapter(const char *func, ...) {
va_list ap;
va_start(ap, func);
cpp_map_int_ptr_adapter_method_lookup(func).execute(ap);
va_end(ap);
}
//...
struct cpp_map_int_ptr_find_adapter : cpp_adapter {
void execute (va_list ap) {
map_int_ptr *map = va_arg(ap, map_int_ptr *);
int key = va_arg(ap, int);
c_map_int_ptr_iterator *c_iter = va_arg(ap, c_map_int_ptr_iterator *);
map_int_ptr::iterator i = map->find(key);
//...transfer result to c_iter
}
};
Where cpp_map_int_ptr_adapter_method_lookup() returns an appropriate cpp_adapter instance based on a table lookup.
I have a bit of pure C++ code which is reading from Objective-C data structures with the help of a function pointer to a method in an Objective C class. I'm treating the Objective-C class instance to read from as an opaque pointer. For example, the C++ method that does the reading has a signature like this:
typedef void(*DataGetterFunc)(void * dataSource, int key, int * outValue);
...
void readData(void * dataSource, DataGetterFunc dataReadingFunc);
When I call the C++ method from Objective-C, I do the following:
MYDataStructure * objectiveCData;
cppObject->readData((__bridge void*)objectiveCData, DataGetterFuncImpl);
Finally, DataGetterFuncImpl dereferences the Objective-C class like so:
void DataGetterFuncImpl(void * dataSource, int key, int * outValue)
{
MYDataStructure * objCData = (__bridge MYDataStructure*)dataSource;
...
}
Originally in DataGetterFuncImpl I was using __bridge_transfer, but then I was getting EXC_BAD_ACCESS the next time ARC called retain on MYDataStructure, So I assumed it was being over-released by the use of __bridge_transfer and changed it to just __bridge.
Are there any memory leaks I should look for by just using __bridge, or do I need to use some combination of __bridge_retain and __bridge_transfer in this case?
When you're using __bridge to convert to or from objc, owership is just not affected. That means, that while you're using the object in C++ you must make sure that there's still a strong reference around.
If you, on the other hand, use __bridge_retain to convert to void* and __bridge_transfer to convert back to id (or any other retainable object type), you must make sure that each __bridge_retain is matched by exactly one __bridge_transfer later.
I need to make COM IntetrOp at runtime using reflections. My native COM Object's exposed methods have some parameters as pointers (DWORD*) and some double pointers (DWORD**) and some are user defined types(e.g SomeUDTType objSmeUDTType) and vice versa its pointer(i.e. SomeUDTType *pSomeUDTType).
Now for dynamic method invocation, we have single option for passing parameters as array of object i.e object[] and filling this array statically.
But I need to pass pointers and references and pointers to pointers. For now how can I be able to populate object array as mixed data of simple data types, pointers or references and pointers to pointers.
Working Example:
Native COM exposed method :
STDMETHODIMP MyCallableMethod(DWORD *value_1,BSTR *bstrName,WESContext **a_wesContext)
Translated by tlbimp.exe (COMInterop)
UDTINIDLLib.IRuntimeCalling.MyCallableMethod(ref uint, ref string, System.IntPtr)
Now calling these methods at runtime using reflection at runtime,
See here :
Assembly asembly = Assembly.LoadFrom("E:\\UDTInIDL\\Debug\\UDTINIDLLib.dll");
Type[] types = asembly.GetTypes();
Type type = null;
//foreach (Type oType in types)
{
try
{
type = asembly.GetType("UDTINIDLLib.RuntimeCallingClass");
}
catch (TypeLoadException e)
{
Console.WriteLine(e.Message);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
object parameters = new object[3];
Type CustomType = asembly.GetType("UDTINIDLLib.WESContext");
object oCustomType = Activator.CreateInstance(CustomType);
FieldInfo fieldInfo = CustomType.GetField("MachineName", BindingFlags.Public | BindingFlags.Instance);
string MachineName = "ss01-cpu-102";
string MachineIp = "127.0.0.1";
string Certificate = "UK/78T";
fieldInfo.SetValue(oCustomType, MachineName);
fieldInfo.SetValue(oCustomType, MachineIp);
fieldInfo.SetValue(oCustomType, Certificate);
object obj = Activator.CreateInstance(type);
MethodInfo mInfo = type.GetMethod("MyCallableMethod");
int lengthOfParams = mInfo.GetParameters().Length;
ParameterInfo [] oParamInfos = mInfo.GetParameters();
object[] a_params = new object[lengthOfParams];
int ValueType = 0;
for(int iCount = 0; iCount<lengthOfParams; iCount++)
{
a_params[iCount] = ???; //Now here this array should be populated with corresponding pointers and other objects (i.e WESContext's obj)
}
mInfo.Invoke(obj, a_params);
Hope code will clarifies ...If any any confusion do let me know I'll edit my question accordingly.
I am stuck here , I'll be obliged if you help me out.(I am confused about "dynamic" keyword might hope it solves the problem)
Is there any need to generate C++/CLI wrappers? and if in which context?
Regards
Usman
Just put the values of your arguments directly into the array. For out/ref parameters, the corresponding elements of the array will be replaced by new values returned by the function.
For the double pointer, by far the easiest approach is to use /unsafe and unmanaged pointers, like so (assuming the parameter is used by the method to return a value):
WESContext* pWesContext; // the returned pointer will end up here
IntPtr ppWesContext = (IntPtr)&pWesContext;
// direct call
MyCallableMethod(..., ppWesContext);
// reflection
a_params[3] = ppWesContext;
mInfo.Invoke(obj, a_params);
After you'll get the pointer to struct in pWesContext, you can use -> to access the members in C#. I'm not sure what memory management rules for your API are, though; it may be that you will, eventually, need to free that struct, but how exactly to do that should be described by the documentation of the API you're trying to call.