Archived OpenModelica forums. Posting is disabled.

Alternative forums include GitHub discussions or StackOverflow (make sure to read the Stack Overflow rules; you need to have well-formed questions)


Forgot password? | Forgot username? | Register

C++ call

C++ call

Hi,
Is it possible calling some C++ function from  OpenModelica C-external function ?
Thanks,
Francesco

Re: C++ call

Yes, but you need to force the compiler to link it in C-mode (no function overloading):

myFile.cpp:
external "C" {

int myFunction(int x) {
  return 3*x;
}

}

Re: C++ call

Thank you very much!
I wasn't sure about it.
Regards,
Francesco

Re: C++ call

I was at the same point some month ago...

You will be in trouble, if your C++ function requires more C++ code or libraries which make C-mode linking impossible.

I decided to use fifos / sockets to interface my C++ stuff then.
So the simulation and the controller software (C++) are seperately build applications exchanging arrays through the socket.

Anyway, i have trouble using my old implementation with the latest version of OM (see my previous thread).

I can provide the code (as soon as it works) if you are interested...

Cheers,
Joerg

Re: C++ call

Yes, mixing C and C++ can be a bit weird, but it's mostly if you include C++ headers in a C file.
If you create a function fn in a C++ file that only calls the C++-function you want to call, and make it linked external "C", and only expose "external int fn(int);" in a header (or the automatically generated code of OMC), you are usually fine. It's always possible to create such an entry point if it doesn't use C++ datatypes.

Re: C++ call

I think I'll use socket to interface the c-function..I've already written a code to receive data during interactive simulation..so I think I could add this new part to the old one..thanks for suggests!

Re: C++ call

Hi!
It seems to be not fast enough.
The cpp-function receives data in a fast way but the return to OM seems slow..
This is the code, it's just for test speed.

Code:



void crea_addr(struct sockaddr_in* addr,int port, char* server)
{
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = inet_addr(server);
addr->sin_port = htons(port);

}

void importExt(int val, double* a,double* b,double* c)
{

               WORD wVersionRequested = MAKEWORD(2,2);
               WSADATA wsaData;
               WSAStartup(wVersionRequested, &wsaData);

            SOCKET sock;

        SOCKADDR_IN addr;

                char buf[100];

    sock=socket(AF_INET, SOCK_STREAM, 0);   
    crea_addr(&addr,10503,"127.0.0.1");

    if(connect(sock, (struct sockaddr*)&addr, sizeof(struct sockaddr))==0)
        {
   
        int n=recv(sock, buf, sizeof(buf), 0);
        closesocket(sock);
        buf[n]=0;
       
        cout<< buf<<" \n";
        *a=0;
        *b=0;
        *c=0;
                 closesocket(sock);
                 return ;
    }
    else
    {
    *a=0;
    *b=0;
    *c=0;
    }

return;
}

As I said the cout is called fast, but results from OMI tu my application are slower..Obviously no problems if I close the socket in my application..
Any suggest?
Thanks,
Francesco

Re: C++ call

Do you connect() every time you exchange data? That seems... Slow. Maybe you could solve it by using a global variable for the connection or external objects instead.

Re: C++ call

Yes I connect everytime because I thougth I couldn't stay connected because the external function is called at every step of the simulation..Maybe I haven't well understood how it works exactly..
Another question..do you think I can declare parameters instead of variables in order to modify them using classical OMI commands? Is this way fast enough in receiving input?
I need to change these values almost every time step.

Re: C++ call

If you have a global variable (or a static local variable), you can store a global state that does not change between function calls.

static int is_initialized = 0;
if (!is_initialized) {
  connect();
  is_initialized = 1;
}
... code goes here; always connected. It's the same connection for all calls to the function though.

As for OMI, I have no clue current/big_smile

Re: C++ call

Hi,
I can't communicate in this way..
Is it possible the socket is automatically closed when the external function returns?
Is there a debug mode for OM ?
thanks for help!

Re: C++ call

Well, you are doing closesocket(sock); And you'd need to make sock and the other data global to save it between calls.

Re: C++ call

Yes, I've done this..or I think I've done current/smile ..this is the new code

Code:


void importExt(int val, double* a,double* b,double* c)
{

static WORD wVersionRequested = MAKEWORD(2,2);
    static WSADATA wsaData;
    WSAStartup(wVersionRequested, &wsaData);

        static SOCKET sock;

        static SOCKADDR_IN addr;

static int is_initialized = 0;
    if (!is_initialized)
    {         

    sock=socket(AF_INET, SOCK_STREAM, 0);   
    crea_addr(&addr,10503,"127.0.0.1");

   
        if(connect(sock, (struct sockaddr*)&addr, sizeof(struct sockaddr))==0);
            is_initialized = 1;
    }


    if(is_initialized)
   
    {
   
        char buf[40]={0};
    send(sock,"\0",sizeof("\0"),0);
    int n;
   
        n=recv(sock, buf, sizeof(buf), 0);
        buf[n]=0;
       
        cout<< buf<<" \n";       
        *a=0;
        *b=0;
        *c=0;

return ;
    }

I can see some exchanges of data (both in OM and in my application) and then all stops waiting for something..but I don't have any result from simulator yet..

Re: C++ call

I solved!
I choosed a bad flag for recv() function..with MSG_PEEK instead of  0 it works..
But it's not fast enough..

Re: C++ call

Fast enough for what? Maybe if you use a fixed size solver it will be faster.

Cheers,
Adrian Pop/

Re: C++ call

I'm just trying to change the numberOfintervals parameter of build() command but I don't understand how it works..
First of all: is this parameter the number of simulation step (and result sendings) in a second (during interactive simulation)?
I tried using 10, 100 and 1000 but the fastest is 100 (WHY? current/sad )

Edited by: De Filippo - Oct-20-10 18:47:06

Re: C++ call

the number of intervals is the number of time steps the simulation will take.
For example, if you simulate from time 0 to 1.0 with 10 intervals, you will get output at 0.0, 0.1, 0.2, 0.3, ..., 1.0

If you have more intervals, the simulation will be slower

Re: C++ call

I'm sorry but I wrote a bad sentence..the fastest for me is 100, the middle value...
and I'm in interactive mode so I can't know how long it takes the simulation..

Re: C++ call

I was wrong again..the MSG_PEEK works because it doesn't clean the buffer and so the receive function always read the first input I send..I didn't notice it before..
I think the external function is called 10-11 times before sending the first results string..but I can't receive it..Maybe there's a problem  in my application..

There are 0 guests and 0 other users also viewing this topic