Assume that I am new to AS3 and FlasCC and try to port some legacy C++ code to Flash. What I have is some number-crunching routine that takes an array of type double (the array is of fixed size). The C++ prototype is, say:
double doNumberCrunching(double input[512]);
Now I would like to build an SWC and later call doNumberCrunching() from AS3. SWIG generates the AS3 interface as:
doNumberCrunching(var _input:*):Number;
However, I have no idea how to feed it with Vector.<Number>(512) without working on raw bytes.
My question is: how to solve it neatly? Do you know a cheap way to access double* underlying the Vector.<Number>? Or something even better?
If only your number crunching function was operating on ints! Then you would be able to use CModule.writeIntVector to write vector contents to DomainMemory and just pass over a pointer to the C++ code.
But since it's doubles, you will have to iterate through Vector and convert each element from AS3 Number to C++ double using CModule.writeDouble. Then you can manually expose your function to AS3 with an interface that accepts a DomainMemory pointer:
void doNumberCrunchingAS() __attribute__((used,
annotate("as3sig:public function doNumberCrunching(inputPtr:int):Number"),
annotate("as3package:mypackage"))
));
double doNumberCrunching( double* input )
{
// Actual implementation here
return 0;
}
void doNumberCrunchingAS()
{
// Read the AS3 argument and convert it to a convenient C++ form.
int memoryOffset = 0;
AS3_GetScalarFromVar(memoryOffset, inputPtr);
double* inputPtr = reinterpret_cast<double*>( memoryOffset );
// Call an implementation routine.
double result = doNumberCrunching( inputPtr );
// Return result to AS3 code.
AS3_Return( result );
}
AS3 code:
package
{
using mypackage.doNumberCrunching;
function testNumberCrunching():void
{
var ptr:int = CModule.malloc(blobSize);
// a loop of writeDouble should be here
doNumberCrunching(ptr);
CModule.free(ptr);
}
}
Related
I would like to implement an interactive shell via UART serial port for Arduino, with pure C++ OOP style code. But I think if there are too many if-else judgements when judging the user input commands in the code, it will be a bit ugly,
So I would like to ask that, is there any way to avoid using if-else statement? For example,
BEFORE:
while(Serial.available())
{
serialReceive = Serial.readString();// read the incoming data as string
Serial.println(serialReceive);
}
if(serialReceive.equals("factory-reset"))
{
MyService::ResetSettings();
}
else if(serialReceive.equals("get-freeheap"))
{
MyService::PrintFreeHeap();
}
else if(serialReceive.equals("get-version"))
{
MyService::PrintVersion();
}
AFTER:
while(Serial.available())
{
serialReceive = Serial.readString();// read the incoming data as string
Serial.println(serialReceive);
}
MagicClass::AssignCommand("factory-reset", MyService::ResetSettings);
MagicClass::AssignCommand("get-freeheap", MyService::PrintFreeHeap);
MagicClass::AssignCommand("get-version", MyService::PrintVersion);
You can have an array that stores a function pointer along with the string that triggers the command (you can create a struct to store both).
Unfortunately Arduino does not support the std::vector class so for my example I will use c type arrays. However there is a library for Arduino that adds some STL support for Arduino https://github.com/maniacbug/StandardCplusplus (also with this library you can use the functional library to make passing functions as arguments easier)
//struct that stores function to call and trigger word (can actually have spaces and special characters
struct shellCommand_t
{
//function pointer that accepts functions that look like "void test(){...}"
void (*f)(void);
String cmd;
};
//array to store the commands
shellCommand_t* commands;
With this you can either initialize the command array to one size on start or resize it every time you add a command, it just depends on your use case.
A basic function that assumes you have already allocated enough space in the array for adding a command could look like this
int nCommands = 0;
void addCommand(String cmd, void (*f)(void))
{
shellCommand_t sc;
sc.cmd = cmd;
sc.f = f;
commands[nCommands++] = sc;
}
Then inside your setup function you can add your commands in a similar fashion as you have above
addCommand("test", test);
addCommand("hello world", helloWorld);
Lastly in your loop function you can use a for loop to look through all of the commands check the input string against all of the command strings.
You can call the function of the matched command like this
(*(commands[i].f))();
I'm trying make a shared library in c++ implementing tools for Fermi gases. I'm using the GSL library to solve a function numerically and my code runs without a problem without when running as a script, but when trying to convert it to a shared library and classes I encounter problems.
I've seen similar questions:
Q1
Q2
Q3
I'm fairly new to c++-programming and cannot seem to adapt the different answers to my problem. Probably since I do not quite understand the answers.
My code is:
/* Define structure for the GSL-function: chempot_integrand */
struct chempot_integrand_params { double mu; double T; };
double
ChemicalPotential::chempot_integrand (double x, void * params){
/* Computes the integrand for the integral used to obtain the chemical potential.
*
* This is a GSL-function, which are integrated using gsl_integration_qag.
*/
// Get input parameters.
struct chempot_integrand_params * p = (struct chempot_integrand_params *) params;
double mu = p->mu;
double T = p->T;
// Initiate output parameters for GSL-function.
gsl_sf_result_e10 result;
int status = gsl_sf_exp_e10_e( ( gsl_pow_2(x) - mu ) / T , &result );
if (status != GSL_SUCCESS){
printf ("Fault in calculating exponential function.");
}
// Return (double) integrand.
return (gsl_pow_2(x) / ( 1 + result.val * gsl_sf_pow_int(10,result.e10) ));
}
/* Define structure for the GSL-function: chempot_integration */
struct chempot_integral_params { double T; };
double
ChemicalPotential::chempot_integration (double mu, double T){
/* Computes the integral used to obtain the chemical potential using the integrand: chempot_integrand.
*/
// Set input parameters for the integrand: chempot_integrand.
struct chempot_integrand_params params_integrand = { mu, T };
// Initiate the numerical integration.
gsl_integration_workspace * w = gsl_integration_workspace_alloc (1000); // Allocate memory for the numerical integration. Can be made larger if neccessary, REMEMBER to change it in the function call: gsl_integration_qag as well.
double result, error;
gsl_function F;
F.function = &ChemicalPotential::chempot_integrand;
F.params = ¶ms_integrand;
// Upper limit for integration
double TOL = 1e-9;
double upp_lim = - T * gsl_sf_log(TOL) + 10;
gsl_integration_qag (&F, 0, upp_lim, 1e-12, 1e-12, 1000, 6, w, &result, &error);
// Free memory used for the integration.
gsl_integration_workspace_free (w);
return result;
}
and when compiling I get the error
error: cannot convert ‘double (Fermi_Gas::ChemicalPotential::*)(double, void*)’ to ‘double (*)(double, void*)’
in line
F.function = &ChemicalPotential::chempot_integrand;
It is indeed interesting that people ask this over and over again. One reason may be that the proposed solutions are not easy to understand. I for one had problems understanding and implementing them. (the solutions did not work out of the box for me, as you might expect.)
With the help of tlamadon I just figured out a solution that may be helpful here as well. Let's see what you guys think.
So just to recap, the problem is that you have a class that contains a member function on which you want to operate with something from the GSL library. Our example is useful if the GSL interface requires a
gsl_function F;
see here for a definition.
So here is the example class:
class MyClass {
private:
gsl_f_pars *p; // not necessary to have as member
public:
double obj(double x, void * pars); // objective fun
double GetSolution( void );
void setPars( gsl_f_pars * xp ) { p = xp; };
double getC( void ) ; // helper fun
};
The objective of this exercise is to be able to
initiate MyClass test,
supply it with a paramter struct (or write a corresponding constructor), and
call test.GetSolution() on it, which should return whatever the GSL function was used for (the minimum of obj, a root, the integral or whatever)
The trick is now to put have an element in the parameter struct gsl_f_pars which is a pointer to MyClass. Here's the struct:
struct gsl_f_pars {
double a;
double b;
double c;
MyClass * pt_MyClass;
};
The final piece is to provide a wrapper that will be called inside MyClass::GetSolution() (the wrapper is a stand in for the member function MyClass::obj, which we cannot just point to with &obj inside the class). This wrapper will take the parameter struct, dereference pt_MyClass and evaluate pt_MyClass's member obj:
// Wrapper that points to member function
// Trick: MyClass is an element of the gsl_f_pars struct
// so we can tease the value of the objective function out
// of there.
double gslClassWrapper(double x, void * pp) {
gsl_f_pars *p = (gsl_f_pars *)pp;
return p->pt_MyClass->obj(x,p);
}
The full example is a bit too long to post here, so I put up a gist. It's a header file and a cpp file, it should be working wherever you have GSL. Compile and run with
g++ MyClass.cpp -lgsl -o test
./test
This is a duplicate question. See Q1 or Q2 for example. Your problem is the following: you cannot convert pointers to member functions to free function pointers. To solve your problem, there are two options. You can define your member function as static (which is bad in 90% of the case because the member function will not be attached to any instantiation of your class and that is why you can convert it to a free function) or you can use the wrapper you linked that will use a static member functions under the hood to make your code compatible with gsl without the need of declaring your particular member function static.
EDIT #Florian Oswald. Basically your entire solution can be implemented in 2 lines using std::bind the wrapper I cited before
gsl_function_pp Fp( std::bind(&Class::member_function, &(*this), std::placeholders::_1) );
gsl_function *F = static_cast<gsl_function*>(&Fp);
In practice is this is just 1 extra line from a pure C code!
As I stated in a comment, wrapping every member function that you want to integrate using an extra global struct and an extra global function is cumbersome and pollute your code with a lot of extra functions/struct that are completely unnecessary. Why use c++ if we refuse to use the features that make C++ powerful and useful (in comparison to C)?
Another classical Example: if you want to pass a LOT of parameters, use lambda functions (no extra struct or global functions) !!!
To be more precise: Imagine you have 2 parameters (doubles) .
//Declare them (locally) here
double a1 = ...;
double a2 = ...;
// Declare a lambda function that capture all of them by value or reference
// no need to write another struct with these 2 parameters + class pointer
auto ptr = [&](double x)->double {/.../};
// Cast to GSL in 3 lines using the wrapper
std::function<double(double)> F1(ptr);
gsl_function_pp F2(F1);
gsl_function *F = static_cast<gsl_function*>(&F2);
No extra global struct of global functions and no extra wrapper (the same wrapper that solved the problem of integrating member function also solved the problem of integrating a lambda expression). Of course this is a matter of style in the end, but in the absence of these nice features that allow the use of C libraries without code bloat, I would never leave C.
I need some advice how can I bind a C/C++ structure to Ruby. I've read some manuals and I found out how to bind class methods to a class, but I still don't understand how to bind structure fields and make them accessible in Ruby.
Here is the code I'm using:
myclass = rb_define_class("Myclass", 0);
...
typedef struct nya
{
char const* name;
int age;
} Nya;
Nya* p;
VALUE vnya;
p = (Nya*)(ALLOC(Nya));
p->name = "Masha";
p->age = 24;
vnya = Data_Wrap_Struct(myclass, 0, free, p);
rb_eval_string("def foo( a ) p a end"); // This function should print structure object
rb_funcall(0, rb_intern("foo"), 1, vnya); // Here I call the function and pass the object into it
The Ruby function seems to assume that a is a pointer. It prints the numeric value of the pointer instead of it's real content (i.e., ["Masha", 24]). Obviously the Ruby function can't recognize this object —I didn't set the object's property names and types.
How can I do this? Unfortunately I can't figure it out.
You have already wrapped your pointer in a Ruby object. Now all you have to do is define how it can be accessed from the Ruby world:
/* Feel free to convert this function to a macro */
static Nya * get_nya_from(VALUE value) {
Nya * pointer = 0;
Data_Get_Struct(value, Nya, pointer);
return pointer;
}
VALUE nya_get_name(VALUE self) {
return rb_str_new_cstr(get_nya_from(self)->name);
}
VALUE nya_set_name(VALUE self, VALUE name) {
/* StringValueCStr returns a null-terminated string. I'm not sure if
it will be freed when the name gets swept by the GC, so maybe you
should create a copy of the string and store that instead. */
get_nya_from(self)->name = StringValueCStr(name);
return name;
}
VALUE nya_get_age(VALUE self) {
return INT2FIX(get_nya_from(self)->age);
}
VALUE nya_set_age(VALUE self, VALUE age) {
get_nya_from(self)->age = FIX2INT(age);
return age;
}
void init_Myclass() {
/* Associate these functions with Ruby methods. */
rb_define_method(myclass, "name", nya_get_name, 0);
rb_define_method(myclass, "name=", nya_set_name, 1);
rb_define_method(myclass, "age", nya_get_age, 0);
rb_define_method(myclass, "age=", nya_set_age, 1);
}
Now that you can access the data your structure holds, you can simply define the high level methods in Ruby:
class Myclass
def to_a
[name, age]
end
alias to_ary to_a
def to_s
to_a.join ', '
end
def inspect
to_a.inspect
end
end
For reference: README.EXT
This is not a direct answer to your question about structures, but it is a general solution to the problem of porting C++ classes to Ruby.
You could use SWIG to wrap C/C++ classes, structs and functions. In the case of a structure, it's burning a house to fry an egg. However, if you need a tool to rapidly convert C++ classes to Ruby (and 20 other languages), SWIG might be useful to you.
In your case involving a structure, you just need to create a .i file which includes (in the simplest case) the line #include <your C++ library.h>.
P.S. Once more, it's not a direct answer to your question involving this one struct, but maybe you could make use of a more general solution, in which case this may help you.
Another option is to use RubyInline - it has limited support for converting C and Ruby types (such as int, char * and float) and it also has support for accessing C structurs - see accessor method in the API.
I want to call a method in a COM component from C# using COM interop. This is the methods signature:
long GetPrecursorInfoFromScanNum(long nScanNumber,
LPVARIANT pvarPrecursorInfos,
LPLONG pnArraySize)
and this is sample code (which I checked is really working) to call it in C++:
struct PrecursorInfo
{
double dIsolationMass;
double dMonoIsoMass;
long nChargeState;
long nScanNumber;
};
void CTestOCXDlg::OnOpenParentScansOcx()
{
VARIANT vPrecursorInfos;
VariantInit(&vPrecursorInfos);
long nPrecursorInfos = 0;
m_Rawfile.GetPrecursorInfoFromScanNum(m_nScanNumber,
&vPrecursorInfos,
&nPrecursorInfos);
// Access the safearray buffer
BYTE* pData;
SafeArrayAccessData(vPrecursorInfos.parray, (void**)&pData);
for (int i=0; i < nPrecursorInfos; ++i)
{
// Copy the scan information from the safearray buffer
PrecursorInfo info;
memcpy(&info,
pData + i * sizeof(MS_PrecursorInfo),
sizeof(PrecursorInfo));
}
SafeArrayUnaccessData(vPrecursorInfos.parray);
}
And here's the corresponding C# signature after importing the typelib of the COM component:
void GetPrecursorInfoFromScanNum(int nScanNumber, ref object pvarPrecursorInfos, ref int pnArraySize);
If I'm not mistaken, I need to pass in null for pvarPrecursorInfos to make COM interop marshal it as the expected VT_EMPTY variant. When I'm doing it, I get a SafeArrayTypeMismatchException - not really surprising, looking at how the result is expected to be handled in the sample. So I was trying to use a custom marshaler. Since a cannot alter the component itself, I tried to introduce it this way:
[Guid("06F53853-E43C-4F30-9E5F-D1B3668F0C3C")]
[TypeLibType(4160)]
[ComImport]
public interface IInterfaceNew : IInterfaceOrig
{
[DispId(130)]
int GetPrecursorInfoFromScanNum(int nScanNumber, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(MyMarshaler))] ref object pvarPrecursorInfos, ref int pnArraySize);
}
The TypeLibType and DispID attribute are the same as in the original version. This works as far as that the MyMarshaller.GetInstance() method is called, but I do not get a callback in MyMarshaller.NativeToManaged. Instead, an access violation is reported. So is this a reliable approach? If yes - how can I make it work? If no: are there any alternatives?
(Just a footnote: in theory I could try to use managed C++ to call the component natively. However, there are lots of other methods in it that work fine with COM interop, so I would very much like to stick with C# if there is any way.)
Since someone asked for it, here's my solution in Managed C++.
array<PrecursorInfo^>^ MSFileReaderExt::GetPrecursorInfo(int scanNumber)
{
VARIANT vPrecursorInfos;
VariantInit(&vPrecursorInfos);
long nPrecursorInfos = -1;
//call the COM component
long rc = pRawFile->GetPrecursorInfoFromScanNum(scanNumber, &vPrecursorInfos, &nPrecursorInfos);
//read the result
//vPrecursorInfos.parray points to a byte sequence
//that can be seen as array of MS_PrecursorInfo instances
//(MS_PrecursorInfo is a struct defined within the COM component)
MS_PrecursorInfo* pPrecursors;
SafeArrayAccessData(vPrecursorInfos.parray, (void**)&pPrecursors);
//now transform into a .NET object
array<PrecursorInfo^>^ infos = gcnew array<PrecursorInfo^>(nPrecursorInfos);
MS_PrecursorInfo currentPrecursor;
for (int i=0; i < nPrecursorInfos; ++i)
{
currentPrecursor = pPrecursors[i];
infos[i] = safe_cast<PrecursorInfo^>(Marshal::PtrToStructure(IntPtr(¤tPrecursor), PrecursorInfo::typeid));
}
SafeArrayUnaccessData(vPrecursorInfos.parray);
return infos;
}
I look at the github code mzLib, which I believe is related to this topic. The code looks good, where it calls
pin_ptr<const wchar_t> wch = PtrToStringChars(path);
I think it may cause some problem, better use
pin_ptr<const wchar_t> pathChar = static_cast<wchar_t*>(System::Runtime::InteropServices::Marshal::StringToHGlobalUni(path).ToPointer());
The code then seems to be worked just fine when compiles. However, it might run in problem when imported as dll. I worked on that by adding a constructor,such as
public ref class ThermoDLLClass
{
public:
ThermoDLLClass();
PrecursorInfo GetPrecursorInfo(int scanNum, String^ path);
};
Then, it seems to get precursorInfo and parameters appropriately.
I'm reading from a binary data file which is written by invoking the following lines in Matlab m-file:
disp(sprintf('template = %d', fwrite(fid, template_1d, 'uint8')));
AFAIK, uint8 is the same size as the types BYTE, unsigned char, and unsigned short. Hence I have written the following code in a file-reading method in a C++ class instantiated in the mexfunction called by Matlab:
template1D = (unsigned short*) malloc(Nimgs*sizeof(unsigned short));
printf("template1D = %d\n", fread(template1D, sizeof(unsigned short), Nimgs, dfile));
and the following is how I deallocated this member variable in the class destructor's helper function:
free((void*) template1D);
In the main mexfunction, when I did not instantiate the class object to persist in memory after mex-function completes by calling mexMakeMemoryPersistent() function, template1D gets cleared properly without segmentation error messages from Matlab. However, if I did instantiate the class to persist in memory as follows:
if (!dasani)
{
dasani = new NeedleUSsim;
mexMakeMemoryPersistent((void*) dasani);
mexAtExit(ExitFcn);
}
with ExitFcn being:
void ExitFcn()
{
delete dasani;
}
then when I'm at the line of free((void*) template1D);, Matlab gives me an error message about the segmentation fault. I have checked the memory sizes and they seem to be consistent. For the malloc/calloc/free functions, I'm using Matlab's mxMalloc/mxCalloc/mxFree functions when I'm executing the C++ project as a Matlab mex function.
Based on this description, what further suggestions would you have for me to solve this problem and ensure this doesn't happen in the future (or at least know how to deal with similar problems like this in the future)?
Thanks in advance.
----------------------------Additions------------------------------------------------------
The following block of code basically shows the jists of my mex file. A mex file is basically an executable that is run in Matlab and compiled from C/C++ code with some Matlab headers.
void ExitFcn()
{
delete dasani;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
needle_info pin;
// check number of i/o if they are correct
if (nrhs != NUMIN)
{
mexErrMsgTxt("Invalid number of input arguments");
}
else if (nlhs != NUMOUT)
{
mexErrMsgTxt("Invalid number of output arguments");
}
// check if the input is noncomplex
if (mxIsComplex(NEEDLE))
{
mexErrMsgTxt("Input must be a noncomplex scalar integer.");
}
// check if the dimensions of the needle information is valid
int needlerows, needlecols;
needlerows = mxGetM(NEEDLE);
needlecols = mxGetN(NEEDLE);
if (needlerows < 1 || needlecols < 6)
{
mexErrMsgTxt("Needle information's dimensions are invalid");
}
float *needlePoint, *yPoint ;
// retrieving current needle information
// order of the variables are always as follows:
// r, theta, l, rho, alpha, beta
needlePoint = (float*) mxGetData(NEEDLE) ;
pin.r = needlePoint[0];
pin.theta = needlePoint[1];
pin.l = needlePoint[2];
pin.rho = needlePoint[3];
pin.alpha = needlePoint[4];
pin.beta = needlePoint[5];
//// read the file inputs
**//if (!dasani)
//{
// dasani = new NeedleUSsim;
// mexMakeMemoryPersistent((void*) dasani);
// mexAtExit(ExitFcn);
//}
dasani = new NeedleUSsim;
delete dasani;**
// sending an useless output for now (get rid of this if not conceptually needed
plhs[0] = mxCreateNumericMatrix(1,1,mxSINGLE_CLASS,mxREAL) ;
yPoint = (float*) mxGetData(plhs[0]) ;
*yPoint = 1;
}
This code would run after build/compilation if the user invokes "mexfunction" anywhere from the command line or m-file script. The snippet enclosed by "**" (when I was trying to bold the snippet) is the problem that I'm looking at. From a second look at the snippet, I may be allocating the memory for dasani pointer in a different memory from the Matlab memory (as there is the memory with scope limited to the C++ mex function only, and another memory space with scope visible to the Matlab program). Otherwise, I'm not sure why Matlab is complaining about this problem.
The MEX API supports C as well as C++. Because C has no try/catch or destructors, there is no way for a C MEX-function to clean-up memory directly in the event of an error. Therefore, MATLAB tracks the results of the memory allocation routines (mxMalloc, mxCalloc, mxRealloc, mxFree, and all the mxCreate* functions that return mxArrays) on an internal list. If an error occurs during the MEX-function execution (either by calling mexErrMsgIdAndTxt directly, or using something like mexEvalString to call MATLAB code that errors), then MATLAB will automatically free any mx-based allocated memory. But, also, when a MEX-function terminates normally, MATLAB will
also free any mx-based memory allocated by the MEX-function. Before the days of destructors, this was a convenience for MEX authors, though in the modern C++ world it can get really annoying.
Sometimes, as in the case of this question, you don't want MATLAB to auto-free memory. In that case, you have to use mexMakeMemoryPersistent, or mexMakeArrayPersistent for mxArrays.
You should only ever pass a pointer to mexMakeMemoryPersistent if it was originally allocated with mxMalloc, mxCalloc, or mxRealloc. So this code
dasani = new NeedleUSsim;
mexMakeMemoryPersistent((void*) dasani);
is bad with a capital 'B', unless you have overloaded NeedleUSsim::operator new() to use mxMalloc, which I wouldn't recommend. But if the fields of dasani are allocated with mxMalloc et al., then you would want to pass those to mexMakeMemoryPersistent. I'd recommend doing something like that in the NeedleUSsim constructor if at all possible, to keep it near the mxMalloc call.
It feels like it's mexMakeMemoryPersistent() that is causing all this trouble. I guess you have to use it to instruct matlab do not delete the memory once it's done. But why should matlab delete the dasani pointer? How is that pointer provided to matlab and what does matlab need it for?
On top of making dasani to be a persistent pointer, I also need to make its member variables with memory allocated by mxMalloc/mxCalloc to be persistent too, for example:
if (!dasani)
{
dasani = new NeedleUSsim;
mexMakeMemoryPersistent((void*) dasani->tplL);
mexMakeMemoryPersistent((void*) dasani->tplR);
mexMakeMemoryPersistent((void*) dasani->tplRho_deg);
mexMakeMemoryPersistent((void*) dasani->tplAlpha_deg);
mexMakeMemoryPersistent((void*) dasani->tplBeta_deg);
mexMakeMemoryPersistent((void*) dasani->hashTb);
mexMakeMemoryPersistent((void*) dasani->template1D);
mexAtExit(ExitFcn);
}
With the destructor as shown:
void NeedleUSsim::Deallocate()
{
free((void*) tplR); free((void*) tplL);
free((void*) tplRho_deg); free((void*) tplAlpha_deg);
free((void*) tplBeta_deg);
free((void*) hashTb);
free((void*) template1D);
}