I have a function in C. I want to call this function from Fortran. This function contains 2 structures passed by pointer. How do I do this in Fortran?
Ex:
struct a
{
int x;
float y;
};
struct b
{
int p;
float q;
};
In C:
fun(*a,*b);
How do I call this from Fortran? Here a is the input structure and b is the output structure. I am able to fill the structures in Fortran but they are unable to maintain any data after passing.
How do I call fun(*a,*b) in Fortran?
If you are using a recent version of Fortran then there should be support for structures or records which should allow you to call the C directly.
If you are using Fortran77 or earlier I would write an interface method in C that took 4 arguments, 2 to represent contents of struct a and 2 to represent struct b. The interface routine would handle the population of the input struct and getting the results from the output struct to the arguments.
I would be tempted to do this even with a modern version of Fortran to avoid potential issues with memory allocation and deallocation. For example if the Fortran is returned memory allocated in the C it may not be possible for the Fortran to deallocate it.
The answer will depend on the version of Fortran you have. In gnu for example, you can use the C_LOC function to get the address.
Related
I know that flexible array member is not part of the C++11 standard.
So what is the correct way of interoperating with C code that return, or accept as argument, structs with flexible array member, from C++11?
Should I write a shim that maps the flexible array member from the C struct to a pointer in C++?
As far as I am aware, standard C++ won't even accept the declaration of a struct with a flexible array member. With that being the case, I see no alternative but to write wrapper functions (in C), unless the structure type containing the FAM can be opaque to your C++ code. I'm uncertain whether a wrapper is the kind of shim you had in mind.
Before we go further, however, I should point out that the problem is substantially different if your C functions accept and return pointers to structures with a flexible array member than if they pass and return the actual structures. I'll assume that they do work with pointers to these structures, for otherwise there seems no point to having the FAM in the first place.
I guess that given a C declaration such as
struct foo {
int count;
my_type fam[];
};
I would represent the same data in C++ as
struct cpp_foo {
int count;
my_type *fam;
};
, which of course can be handled by C, as well. Be aware that you cannot successfully cast between these, because arrays are not pointers.
Given a C function
struct foo *do_something(struct foo *input);
the needed wrapper might then look like this:
struct cpp_foo *do_something_wrap(struct cpp_foo *input) {
struct cpp_foo *cpp_output = NULL;
// Prepare the input structure
size_t fam_size = input->count * sizeof(*input->fam);
struct foo *temp = malloc(sizeof(*temp) + fam_size);
if (!temp) {
// handle allocation error ...
} else {
struct foo *output;
temp->count = input->count;
memcpy(temp->fam, input->fam, fam_size);
// call the function
output = do_something(temp);
if (output) {
// Create a copy of the output in C++ flavor
cpp_output = malloc(sizeof(*cpp_output));
if (!cpp_output) {
// handle allocation error
} else {
fam_size = output->count * sizeof(output->fam[0])
cpp_output->fam = malloc(fam_size);
if (!cpp_output) // handle allocation error
memcpy(cpp_output->fam, output->fam, fam_size);
// Supposing that we are responsible for the output object ...
free(output);
}
} // else cpp_output is already NULL
free(temp);
}
return cpp_output;
}
Naturally, if you have several functions to wrap then you probably want to write reusable conversion functions to simplify it.
There's a trick used by Windows by setting the flexible array member to have size 1 (because the Win32 API has been developed long before the feature ever went into C99, let alone C++)
struct foo {
int count;
my_type fam[1];
};
If you're allowed to change the C version then use the same struct in both C and C++. In case you can't change the C version then you'll need to redefine the struct in C++. You still have to change the C++ code when the C struct was modified, but at least it'll compile fine
See also
Are flexible array members valid in C++?
Why do some structures end with an array of size 1?
As flexible array members cannot to exposed to C++ (my_type fam[]; is not a valid C++ member), we'll have to define your own type.
Luckily C linkage functions don't have symbols that depend on their arguments. So we can either modify the definition of foo within shared headers, or define our own and don't include their headers.
This is a struct that is likely to be compatible layout-wise. Note that you should never declare these on the stack in C++:
struct foo {
int count;
#ifndef __cplusplus
my_type fam[];
#else
my_type do_not_use_fam_placeholder;
my_type* fam() {
return &do_not_use_fam_placeholder;
}
my_type const* fam() const {
return &do_not_use_fam_placeholder;
}
#endif
};
This relies upon the binary layout of the foo structure in C to be the prefix members, followed by the flexible array member's elements, and no additional packing or alignment be done. It also requires that the flexible array member never be empty.
I would use this+1 but that runs into alignment issues if there is padding between count and fam.
Use of memcpy or memmov or the like on foo is not advised. In general, creating a foo on the C++ side isn't a good idea. If you have to, you could do something like this:
struct foo_header {
int count;
};
foo* create_foo_in_cpp(int count) {
std::size_t bytes = sizeof(foo)+sizeof(my_type)*(count-1);
foo* r = (foo*)malloc(bytes);
::new((void*)r) foo_header{count};
for (int i = 0; i < count; ++i)
::new( (void*)(r->fam()+i) my_type();
return r;
};
which constructs every object in question in C++. C++'s object existence rules are more strict than C's; merely taking some POD memory and interpreting it as a POD is not a valid action in C++, while it is in C. The news above will be optimized to noops at runtime, but are required by C++ to declare that the memory in question should be treated as objects of that type under strict reading of the standard.
Now, there are some standard issues (defects) with manually per-element constructing the elements of an array, and layout-compatibility between arrays and elements, so you'll have to trust somewhat that the ABI of the C++ compiler and the C code is compatible (or check it).
In general, all interop between C and C++ is undefined by the C++ standard (other than some parts of the standard C library which C++ incorporates; even here, there is no mandate that C++ use the same C library). You must understand how your particular implementation of C and C++ interoprate.
Recently for fun I have decided to build a toy programming, compiler and vm. While starting to implement the virtual machine I got stuck. The stack which holds the variables and structs I implemented as separate arrays for each type. The problem is when I have a reference to a struct the elements are not aligned, int struct.x might be at address 2, and float struct.y might be at address 56, so accessing the struct by a reference would be impossible, because the indexes are not linear. How could I solve this?
edit:
first of all for each type I mean for each primitive, and second I know I could implement it with unions but I want to learn how it is really implemented in java, c++ or c#, that's kind of the point of making a toy language, to better understand what you are programming.
in this case, you have no real choice but to use a single data type like a uin32_t/uint64_t and simply have the compiler break values down into integer
int sp = 0;
uint32_t stack[MAX_STACK_SIZE];
OR
like the others have said, create a stack that is an array of unions, possibly using a tagged union. One implementation could be...
union values {
int i;
float f;
};
struct Type {
int tag;
union values val;
};
Type stack[MAX_STACK_SIZE];
It's up to you to decide on this but this is usually how it's done.
In C++ the only way to pass an array to a function is by pointer, considering following
functions:
void someFunc(sample input[7]){
//whatever
}
void someFunc(sample input[]){
//whatever
}
void someFunc(sample (& input)[7]){
//whatever
}
All above function parameters are identical with following function parameter when the function is not inlined:
void someFunc(sample * input){
//whatever
}
Now to pass the array with value we have to put it in a structure like below:
struct SampleArray{
public:
sample sampleArray[7];
};
Now I'd like to know if anyone knows the reason behind this design in C++ standard that makes passing pure arrays by value impossible by any syntax and forces to use structs.
Backward compatibility reasons. C++ had no choice but to inherit this behavior from C.
This answer to the earlier similar question addresses the reasons why such behavior was introduced in C (or, more specifically, why arrays and arrays within structs are handled differently by the language).
C++ adopted that part of C, but added the ability to pass arrays by reference (note that your third version of someFunc passes the array by reference, and is not equivalent to using a pointer to its first element). In addition, C++ includes various container types that can be passed by value (recently including std::array)
Probably as a function of its C ancestry. Arrays being just pointers to memory it'd be kind of hard for that to be done transparently without generating extra code by the compiler. Also it's trivial to implement a container class that does lazy copy on write, which will perform better.
So it's been a while since I've used straight C. And I'm on a project where I'm working on an API in C++. Most of these methods are just C anyway, and all of the return values are C structures. Except one. One method I need to return a vector<string>. Now here's my question. Is C++ methods/libraries/whatever callable from C? I ask because I don't know if the people using the API are going to be writing in C or C++, and I feel like I should be returning only C structures. That would require me to return a char**, right?
I hope that made sense, if not:
tl;dr version - Can I call a C++ method from C if it returns a C structure, and if so is the best (only?) equivalent return value of vector<string> -> char**?
Update: The C++ methods are simply global methods. There's no classes or object oriented stuff in them. The ONLY thing that's specific to C++ other than my vector question is a few stringstreams
No, C cannot use C++ features that are not also available in C. However, C code can make use of C++ code indirectly. For example, you can implement a C function using C++, and you can use opaque types in the interface so that the signature uses void*, but the implementation uses a C++ class.
The equivalent of vector<string> in C is probably closer to:
typedef const char* c_string_type;
typedef struct c_string_array {
c_string_type* c_strings;
int c_strings_count;
} c_string_array_t;
With opaque types, you would have something along the lines of:
typedef void* c_string_array_t;
int c_string_array_length(c_string_array_t array);
const char* c_string_array_get(c_string_array_t array, int index);
You could then secretly (in the C++ implementation) cast std::vector* to void*.
You can technically call anything from C, as long as a C-visible function name is given (prototypes etc. are ignored at the ABI level). Of course you can't expect correct results if C isn't able to generate the parameters in the expected fashion. Generally the obvious solution is to simplify the interface down to the C level. char ** is an excellent choice for greatest common denominator with a vector<string>. Not only that, if you know what you intend to do with it, quite possibly faster (and cleaner IMHO).
With respect to the C visibility: The function name cannot be shared with any other C visible functions. If you wish your C++ function to be callable from C, this might be a good example of the prototype:
extern "C" char **lots_of_strings();
If the parameter signature differs, C++ will let you overload with functions visible only from C++, and allow them to coexist with the C version:
vector<string> lots_of_strings(int);
extern "C" char **lots_of_strings();
If you wanted to provide several ways to call it, appropriate for the calling language, you might try this (ignoring the evils of late initialization, and the fact that bool exists in C):
bool lots_of_strings(vector<string> &);
extern "C" int lots_of_strings(char ***);
Whatever lots_of_strings(SomeArrayType &);
Keeping in mind that in every case, C++ will choose the definition with the best matching signature to the call site, and C will take whatever it can (which is always a single function with a matching name).
You'll find it useful to hide C++isms from C by combining #ifdef with the macro __cplusplus.
See this FAQ. Basically, you can't call C++ methods (member functions), but you can call free-standing functions if they're declared with extern C. char ** is not the only possibility, but it's probably the most straight-forward. You can return a dynamically allocated array of char *. You will have to use an out parameter to provide the length to the caller (you could NULL-terminate it, but that's probably not ideal). E.g.
char **get_string_list(size_t *len)
{
char **array;
size_t actual_len;
// ...
*len = actual_len;
array = (char **) malloc(sizeof(char *) * actual_len);
// ...
return array;
}
You must somehow free the memory. Either provide a function or document how the caller should do it. Don't forget to free the individual strings if they're dynamically allocated.
I read some lines about this some time ago, and iirc you can use c++ code/structures that would compile in C. But there is some thing about static initialisation, if i understood correct, you should write your main function in c++ to guarantee that this s.i. is done, C main does not do.
If you intend to offer the same functionality to both C and C++ I would try to offer two entry points so that you can adapt one to the other. Note that while you can settle for an interface that can be used both from C and C++, in most cases the C interface will not be ideal for C++ usage (using char** might be a good solution for C, but having users convert that back to C++ types and performing cleanup can clutter user code) and vice versa.
If you have the possibility to modify the code that you're calling I would suggest changing the function from returning an vector to something like:
unsigned int MyFunction(char* buff, unsigned int numLines, unsigned int stride)
Where numLines is the amount of allocated strings and stride is the size of the strings. That way your function doesn't need to allocate any memory that you need to worry about later. It's all handled by the caller. The return value of the function is the amount of strings that was used.
Is it possible to write a C++ class or struct that is fully compatible with C struct. From compatibility I mean size of the object and memory locations of the variables. I know that its evil to use *(point*)&pnt or even (float*)&pnt (on a different case where variables are floats) but consider that its really required for the performance sake. Its not logical to use regular type casting operator million times per second.
Take this example
Class Point {
long x,y;
Point(long x, long y) {
this->x=x;
this->y=y;
}
float Distance(Point &point) {
return ....;
}
};
C version is a POD struct
struct point {
long x,y;
};
The cleanest was to do this is to inherit from the C struct:
struct point
{
long x, y;
};
class Point : public struct point
{
public:
Point(long x, long y)
{ this->x=x; this->y=y; }
float Distance(Point &point)
{ return ....; }
}
The C++ compiler guarantees the C style struct point has the same layout as with the C compiler. The C++ class Point inherits this layout for its base class portion (and since it adds no data or virtual members, it will have the same layout). A pointer to class Point will be converted to a pointer to struct point without a cast, since conversion to a base class pointer is always supported. So, you can use class Point objects and freely pass pointers to them to C functions expecting a pointer to struct point.
Of course, if there is already a C header file defining struct point, then you can just include this instead of repeating the definition.
Yes.
Use the same types in the same order in both languages
Make sure the class doesn't have anything virtual in it (so you don't get a vtable pointer stuck on the front)
Depending on the compilers used you may need to adjust the structure packing (usually with pragmas) to ensure compatibility.
(edit)
Also, you must take care to check the sizeof() the types with your compilers. For example, I've encountered a compiler that stored shorts as 32 bit values (when most will use 16). A more common case is that an int will usually be 32 bits on a 32-bit architecture and 64 bits on a 64-bit architecture.
POD applies to C++. You can have member functions. "A POD type in C++ is an aggregate class that contains only POD types as members, has no user-defined destructor, no user-defined copy assignment operator, and no nonstatic members of pointer-to-member type"
You should design your POD data structures so they have natural alignment, and then they can be passed between programs created by different compilers on different architectures. Natural alignment is where the memory offset of any member is divisible by the size of that member. IE: a float is located at an address that is divisible by 4, a double is on an address divisible by 8. If you declare a char followed by a float, most architectures will pad 3 bytes, but some could conceivably pad 1 byte. If you declare a float followed by a char, all compilers (I ought to add a source for this claim, sorry) will not pad at all.
C and C++ are different languages but it has always been the C++'s intention that you can have an implementation that supports both languages in a binary compatible fashion. Because they are different languages it is always a compiler implementation detail whether this is actually supported. Typically vendors who supply both a C and C++ compiler (or a single compiler with two modes) do support full compatibility for passing POD-structs (and pointers to POD-structs) between C++ code and C code.
Often, merely having a user-defined constructor breaks the guarantee although sometimes you can pass a pointer to such an object to a C function expecting a pointer to a struct with and identical data structure and it will work.
In short: check your compiler documentation.
Use the same "struct" in both C and C++. If you want to add methods in the C++ implementation, you can inherit the struct and the size should be the same as long as you don't add data members or virtual functions.
Be aware that if you have an empty struct or data members that are empty structs, they are different sizes in C and C++. In C, sizeof(empty-struct) == 0 although in C99, empty-structs are not supposed to be allowed (but may be supported anyway as a "compiler extension"). In C++, sizeof(empty-struct) != 0 (typical value is 1).
In addition to other answers, I would be sure not to put any access specifiers (public:, private: etc) into your C++ class / struct. IIRC the compiler is allowed to reorder blocks of member variables according to visibility, so that private: int a; pubic: int b; might get a and b swapped round. See eg this link: http://www.embedded.com/design/218600150?printable=true
I admit to being baffled as to why the definition of POD does not include a prohibition to this effect.
As long as your class doesn't exhibit some advanced traits of its kind, like growing something virtual, it should be pretty much the same struct.
Besides, you can change Class (which is invalid due to capitalization, anyway) to struct without doing any harm. Except for the members will turn public (they are private now).
But now that I think of your talking about type conversion… There's no way you can turn float into long representing the same value or vice versa by casting pointer type. I hope you only want it these pointers for the sake of moving stuff around.