Reputation: 131
I have two moudles:
Module1: A C program, constructs two graphs.
Module2: A C++ program, checks equivalence of the two graphs produced by module1.
I want to feed output of module1 to module2.
Module2 uses structs only and are identical to ones used in module1, only difference is that module2 contains some function overloading etc.
One way to transfer the graphs is to write them to a file and re-read and parse in module2.
My Question is:
Is there a method available by which I can carry the instances of structs constructed in Module1 to Module2 directly, without going through this file read/write.
Abstract example of what I want to say:
// Module1:
struct s1 {
int a;
};
void main (){
struct s1 s;
s.a = 10;
}
// Module2:
struct s1{
int a; // Note the same structure and variable name.
};
void print (struct s1 s){
cout << s.a;
}
void main (){
struct s1 s;
print (s);
}
Question repharsed: Is there a technique available by which I can feed the structure created in Module1 directly (via main memory only) to Module2; without writing to file first and then re-reading?
Upvotes: 3
Views: 287
Reputation: 9817
As answered by @Galik, both modules can be linked to a single program. As an alternative, the message passing interface (MPI) can be used to communicate pieces of information from a program to another. Here is how it could be done in your case.
module2
spawns a process calling module1
.module1
sets the value of the member of a struct s1 s
and sends the structure as a buffer to module2
. module2
receives a copy of the buffer, puts it into a struct s1 and prints the value of the member.Here is the c++ code of program module2
, to be compiled by mpiCC module2.cpp -o module2
:
#include <iostream>
using namespace std;
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
struct s1{
int a; // Note the same structure and variable name.
};
void print (struct s1 s){
cout << s.a;
}
int main (int argc, char *argv[])
{
int errcode;
MPI_Comm intercomm,intracomm;
MPI_Info info;
MPI_Init( &argc, &argv );
char command[15];
sprintf(command,"%s","./module1");
int ierr=MPI_Comm_spawn(command,MPI_ARGV_NULL,1,MPI_INFO_NULL,0,MPI_COMM_WORLD,&intercomm,&errcode);
if (ierr != MPI_SUCCESS) {
printf("spaw failed\n");
}
// intercomm has two group. One with the parent, one with the children
MPI_Intercomm_merge(intercomm,0,&intracomm);
int size, rank;
MPI_Comm_size(intracomm, &size);
MPI_Comm_rank(intracomm, &rank);
cout<<"parent has rank "<<rank<<" in communicator of size "<<size<<endl;
struct s1 s;
MPI_Recv(&s,sizeof(struct s1),MPI_CHAR,1,0,intracomm,MPI_STATUS_IGNORE);
MPI_Comm_disconnect(&intracomm); //disconnect after all communications
MPI_Comm_disconnect(&intercomm);
print (s);
cout<<endl;
MPI_Finalize();
return 0;
}
Here is the c code of program module1
, to be compiled by mpicc module1.c -o module1
:
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct s1 {
int a;
};
int main(int argc,char *argv[])
{
int rank,size;
MPI_Comm parentcomm,intracomm;
MPI_Init( &argc, &argv );
//MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_get_parent( &parentcomm );
if (parentcomm == MPI_COMM_NULL){fprintf(stderr,"module1 : i'm supposed to be the spawned process!");exit(1);}
MPI_Intercomm_merge(parentcomm,1,&intracomm);
MPI_Comm_size(intracomm, &size);
MPI_Comm_rank(intracomm, &rank);
printf("child had rank %d in communicator of size %d\n",rank,size);
struct s1 s;
s.a = 10;
MPI_Send(&s,sizeof(struct s1),MPI_CHAR,0,0,intracomm);
MPI_Comm_disconnect(&intracomm); //disconnect after all communications
MPI_Comm_disconnect(&parentcomm);
MPI_Finalize();
return 0;
}
The whole thing is ran by mpirun -np 1 module2
.
Upvotes: 0
Reputation: 48625
There is no reason the two modules can't be linked together into a single program. The main thing to remember is that the C
function declarations (in the C
header file module1.h) need to be marked as having C
language linkage to the C++
compiler.
You can do that using __cplusplus
guards:
module1.h
#ifndef MODULE_1_H
#define MODULE_1_H
// tell the C++ compiler this header is for
// a module written in C
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
int i;
double d;
} Graph;
Graph construct_a_graph();
#ifdef __cplusplus
} // extern "C"
#endif
#endif // MODULE_1_H
module1.c
#include "module1.h"
Graph construct_a_graph()
{
Graph g;
g.i = 2;
g.d = 7.9;
return g;
}
module2.h
#ifndef MODULE_2_H
#define MODULE_2_H
#include "module1.h"
void process_graph(Graph g);
#endif // MODULE_2_H
module2.cpp
#include "module2.h"
void process_graph(Graph g)
{
// do stuff in C++
}
main.cpp
#include "module1.h"
#include "module2.h"
int main()
{
Graph g = construct_a_graph(); // C function
process_graph(g); // C++ function
}
Compiling with GCC:
gcc -c -o module1.o module1.c // C module
g++ -c -o module2.o module2.cpp // C++ module
g++ -o main main.cpp module1.o module2.o // link fine
Upvotes: 5
Reputation: 4275
I think the easiest solution would be to make a library (.dll/.so/..) out of both, that contains the implementation of the class and provides a C- and a C++-interface for accessing it.
You can then either store the instances of your objects in the library and pass handles/copies to the user (depending on what you need) or use the shared memory and pass pointers between your modules. Under VisualStudio the shared-memory-option is called "Multithreaded-DLL (\Md)", i don't know the exact option for other OS/Compilers.
Upvotes: 0