So I am trying to send the names of functions called through call instructions I find in a program to an external function as a string. So the declaration of my external function is: void func(string s); In my LLVM pass I am trying to pass a value to the parameter s. I am stuck at adding the function declaration of func using getOrInsertFunction, here is a code snippet:
Function * func;
Constant * funcDec = M.getOrInsertFunction("func",
Type::getVoidTy(M.getContext)), ???);
I am confused about what to put in place of ???.
As an example Type::getInt32Ty(M.getContext()) is used if the parameter is int. I know LLVM doesn't have std::string. So how can I achieve passing a string to an external function?
Thanks!
String is basically character pointer. Char is 8 bit. So you can put
Type::getInt8PtrTy(M.getContext()) in place of ???.
Related
I'm using VxWorks 6.9 and am trying to use some spyLib.h functions but I'm having issues finding what signature to expect given that the type is variadic.
in vxTypesOld.h I find my type: typedef int (*FUNCPTR) (...);
and in spyLib.h i have my function call : extern void spyReportCommon (FUNCPTR printRtn);
But what function parameters are expected for printRtn ? I guess a c-style string is one but I don't know if each line of the table is a string or if its an array of strings, or even one large string.
I can't start writing the function to parse data from the outputted data until I know in what form that data is passed into the function.
All I know for certain is that it returns an int (e.g. int parsePrint( ???? );)
Here is my attempt at reporting:
#include <vxworks.h>
#include <spyLib.h>
#include <usrLib.h>
int ParseSpy(const char * spyOutput); // this is a guess
void Startup()
{
//startup logic
// the compiler said and int param is expected but the .h had void
spyLibInit(1);
spyCommon(1,50, (FUNCPTR) &ParseSpy);
}
int ParseSpy(const char * spyOutput){} // this is a guess
I'm getting an unexpected compiler error: 'spyCommon' was not declared in scope
but as you can see spyLib.h was included so I'm a bit confused by this.
That looks like a bad design. The print function cannot print if it does not know what the parameters are. At least one parameter is needed to specify what the rest of the parameters are.
Looking at the source and searching for "printRtn" I see that all calls to the print function are expecting a printf like function where the first parameter is a format string. Your function should better be written as
int ParseSpy(const char * spyOutput, ...);
Regarding the missing spyCommon you could try to let VxWorks write the preprocessor output to a file to check what the compiler sees. Maybe you are getting the wrong spylib.h file or something it that file is hidden by #if.
I have a compiled a library and I am trying to access the functions from c++ code. Most functions work properly, however I have some trouble with passing parameters to a function that accepts an array as argument.
The pascal function header is defined as:
function MyFunc( const Name : PAnsichar;
const MyArr : array of single;
const ArrLength : Longint;
var output : single
): Longint;
I can compile this function and use is properly when using pascal to load the function and call the functions in the library. Note: the library is compiled using the CDecl calling convention.
However I have trouble with loading the functions in C++.
The function is defined as:
typedef long (*MyFunc)(char *, float, long, float *);
I am able to load the dll properly and acces all the function properly, all but the one above.
long ArrLeng = 300;
float out;
float Arr[ArrLeng];
\\ fill the array
result = MyFunc((char *) "default", Arr[0], ArrLeng, &out);
I can attach the debugger to the library and check the variables read by the library. The strange thing is that the Name and ArrLeng variables are passed on properly, but the array is not passed properly.
What am I doing wrong? How should I pass the array to the library?
Try passing a pointer to the first element. "Array of Single" is a so called open array which is a pascal construct that also passes array boundary information.
However when used in combination with cdecl afaik it reduces to a pointer to elementtype. (single *) At least Free Pascal does, I don't know what Delphi/Kylix does.
In doubt let pascal call it and check the resulting assembler.
I am trying to get the Aruco AR library working by trying out the simple test in my code.
For some reason I cannot get the call to detect() to work. My code is as follows:
cv::Mat image(480,640,CV_8UC3, mimFrameRGB.data());
MarkerDetector mDetector;
std::vector<Marker> markers;
CameraParameters cParams();
float markerSize = 0.1f;
mDetector.detect(image,markers,cParams,markerSize);
The compiler complains that there is no overloaded function that matches my input parameters. Specifically that parameter 3 should be of type cv::Mat.
Looking at the header file for the MarkerDetector, the following two method calls are found:
void detect(const cv::Mat &input,std::vector<Marker> &detectedMarkers,cv::Mat camMatrix=cv::Mat(),cv::Mat distCoeff=cv::Mat(),float markerSizeMeters=-1) throw (cv::Exception);
void detect(const cv::Mat &input,std::vector<Marker> &detectedMarkers, CameraParameters camParams,float markerSizeMeters=-1) throw (cv::Exception);
I am trying to call the second one, however it chooses the first one and gives me a compile error. What is going wrong? are my input parameters not matching either case?
I think the issue is this line:
CameraParameters cParams();
This does not declare a variable of type CameraParameters, but instead is a function prototype for a function called cParams that takes no parameters and returns a CameraParameters. This is an extremely annoying part of the C++ language, since the code is legal but doesn't do what you want.
Because cParams is actually a function prototype and not a variable declaration, the C++ overload resolution mechanism is getting confused about the types of the arguments and is failing to correctly select the oveload you'd like. Removing the parentheses on this line and having it just read
CameraParameters cParams;
should fix this problem.
Hope this helps!
The problem is; when you declare cParams like CameraParameters cParams(); you are actually declaring a function named cParams which returna a CameraParameters. It should be CameraParameters cParams; (Remove paranthesis).
I'm betting it's because:
CameraParameters cParams();
which actually declares a function cParams taking no arguments and returning a CameraParameters.
So when you call the method and pass it cParams, it interprets that as a function pointer, which is probably why it chooses the first variant.
Replace it with:
CameraParameters cParams;
I have an array of function pointers like this:
void (*aCallback[10])( void *pPointer );
I am assigning functions to the array like that:
aCallback[0] = func_run;
aCallback[1] = func_go;
aCallback[2] = func_fly;
The names like "run", "go", "fly" are stored in another array.
Is it possible to assign the functions to the function-array using a char? Something like:
char sCallbackName[64];
sprintf(sCallbackName, "func_%s", "run");
aCallback[0] = sCallbackName; //caCallback[0] = "func_run"; doesn't work of course
Not directly, no. The symbol table and other meta-information is generally not available at runtime, C++ is a compiled language.
The typical way to solve it is to use some macro trickery, perhaps along the lines of this:
/* Define a struct literal containing the string version of the n parameter,
* together with a pointer to a symbol built by concatenating "func_" and the
* n parameter.
*
* So DEFINE_CALLBACK(run) will generate the code { "run", func_run }
*/
#define DEFINE_CALLBACK(n) { #n, func_##n }
const struct
{
const char* name;
void (*function)(void *ptr);
} aCallback[] = {
DEFINE_CALLBACK(run),
DEFINE_CALLBACK(go),
DEFINE_CALLBACK(fly)
};
The above code has not been compiled, but it should be at least close.
UPDATE: I added a comment next to the macro to explain it a bit. The # and ## operators are semi-obscure, but totally standard, well-known, and their use always crops up in cases like these.
# is the quoting or stringizing operator.
## is the token concatenation operator.
That is not possible.
The functions are not accessible by name at runtime because the compiler translates a name to a memory address.
This is not possible in vanilla C++.
Scripting languages like PHP has this facility because they are interpreted language. With a language, such as C, which compiles the code prior to running, you don't have such facility.
I have to classes, an Executer with these methods:
Executer()
struct Execute(string s)
Lookup(string name, int module, int num, ...)
and a Parser:
Parser()
struct Parse(string s)
The Exectuers Execute method calls the Parsers Parse method. The Parser then chucks the string into smaller bits (it explodes the string on the ;-sign) and returns a struct to the Execute method. This struct it uses to call the Lookup method.
The struct that the Parse returns holds some standard information:
An command name
A senderId (a username, a mac address and a password)
A variable number of arguments
And that is my problem. The Lookup method take variable arguments, but how do I handle the the hand over of these variable arguments by the struct? Im not an expert in C and C++. Should I mass the two classes togheter? So the Parser method could call the Execute method, sparing the struct away.
Or maybe there is a way of parsing an unknown variable of arguments at runtime? By some sort of array?
EDIT
I cant use the STL library from C++. I only use the C++ class and virtual feature. Im writing to an compiler where Im restricted to use almost all of the C libraries + the magic skills of C++ (virtual and class). SOory for not telling that right away.
EDIT 2
Im writing code to an embedded system and thereby using avr-gcc to compile my code. Thats why I cant use STL. The avr-gcc doesnt support this.
Use std::vector<> or a simular container that can hold an arbitrary number of entries.
struct {
std::string commandName;
sender_t senderId;
std::vector<arg_t> arguments;
};
Edit: oh, you can't use std::vector. In that case: use an array and store the length:
struct {
const char* commandName;
sender_t senderId;
int argumentCount;
int maxArgumentCount; // you might not need this
arg_t* arguments; // pointer to array of (at least) argumentCount elements.
};
Use malloc() or new() to create the array for the arguments.
I would suggest to wrap the argumentCount, maxArgumentCount and arguments in a separate class, which can handle the malloc/new and free/delete as well. This will make it easier to prevent memory leaks.
In the end, you'll have written your own vector_of_arg_t class, so maybe have a look at some basic vector implementation. There must be tutorials on that on the web.
You could declare your Lookup method as follows:
void Lookup(string name, int module, int num, std::vector<std::string> &args);
By storing the variable arguments in an args array, you can have as many as you want.
See
Q: How can I write a function which takes a variable number of arguments and passes them to some other function (which takes a variable number of arguments)?
A: In general, you cannot. Ideally, you should provide a version of that other function which accepts a va_list pointer.
Suppose you want to write a faterror function which will print a fatal error message, then exit. You might like to write it in terms of the error function of question 15.5:
void faterror(const char *fmt, ...)
{
error(fmt, what goes here? );
exit(EXIT_FAILURE);
}
but it's not obvious how to hand faterror's arguments off to error.
<snip>
Read on at
http://c-faq.com/varargs/handoff.html