How to pass a C structure to a C library callback?

Shockwave vinfobag at gmail.com
Wed Mar 2 20:24:53 UTC 2011


What is the proper way to pass a C struct from the application embeeding
parrot to one of the libraries used from the generated PIR code?

 

So far, I've being trying to send the struct as a void*, converted to an
int, as the one argument to the :main sub. But I can't get it to work.

 

The following function calls the :main function and passes it an int
successfully.

 

bool

VMachine::execute(request_rec* request)

{

     WebBundle* wb = nullptr;

     std::auto_ptr<WebBundle> bundle(wb = new WebBundle(request));

 

     // Convert the WebBundle struct to an int.

     Parrot_PMC intVal;

     Parrot_api_pmc_box_integer(mInterp, reinterpret_cast<int>(wb),
&intVal);

 

     Parrot_PMC mainFunc;

     Parrot_api_ready_bytecode(mInterp, mBytecode, &mainFunc);

 

     Parrot_PMC mCtxClass;

     Parrot_PMC contextClassName = NULL;

     Parrot_PMC sig = NULL;

     Parrot_String str;

 

     // Create a CallContext in which the function will run.

    Parrot_api_string_import_ascii(mInterp, "CallContext", &str);

    Parrot_api_pmc_box_string(mInterp, str, &contextClassName);

    Parrot_api_pmc_get_class(mInterp, contextClassName, &mCtxClass);

    Parrot_api_pmc_new_from_class(mInterp, mCtxClass, NULL, &sig);

 

     // Create the function signature.

     Parrot_api_string_import_ascii(mInterp, "vp", &str);

    Parrot_api_pmc_set_string(mInterp, sig, str);

     //Parrot_api_string_import_ascii(mInterp, "main", &str);

    Parrot_api_pmc_set_keyed_int(mInterp, sig, 0, intVal);

 

     // Run the main method.

     if (!Parrot_api_pmc_invoke(mInterp, mainFunc, sig)) {

           checkErrors(request);

           return false;

     }

 

     return true;

}

 

 

 

The value of the argument to main is read correctly from within the main
sub.

 

.sub 'main' :main

                .param int _handle

 

                $P1 = open "C:/log.txt", "w"

                print $P1, _handle # The value of _handle is written
correctly.

                close $P1

 

                # ...

.end

 

However, I can't find a way to pass the value of that int to a C callback:

 

Here's how the C function is loaded and called:

 

                                                .local pmc lib

                                                .local pmc function


                                                lib = loadlib "libtest"

                                                function = dlfunc  lib,
"print", "vpt"          

                                                function(_handle, "some
message");                                     

 

I tried changing the 'p' in the signature 'vpt' to most of letters: i, I, 3,
4, p, P,t - Only the lowercase p seems to work and not stop the program.

 

The function, which is shown below, is called, with the correct second
parameter. However, I need to make the first parameter be the C structure

That is being passed from the embedding application.    

 

void print(void* data, const char* msg)

     // HOW TO MAKE USE OF the C struct 'data'

 

     std::ofstream file("C:/ print.log", std::ios::app);

     file << msg << "\n";

     file.close();

}

 

 

 

 

 

Regards,

vlad

 

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.parrot.org/pipermail/parrot-dev/attachments/20110302/7567e12f/attachment.html>


More information about the parrot-dev mailing list