Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
My previous post covered one way of "how to do it". This is a separate post because the focus is on "why are you doing that?" and a re-coding of your original code.

I did some bit of "mind reading" and re-coded your C function. It looks like you wanted 2 different ways for your function to return the result? If you gave it a "ret string", you wanted that string modified "in place"? Otherwise you wanted a new result to be passed to $output? Very confusing to me. Please un-confuse me.

Anyway, I don't see the need for this "ret" input parm at all. Take in a string, do something that generates another string and return that string. What is the need for this second input string? It is possible to modify a string "in place", but that would require the caller to provide enough memory so that when the string becomes longer, it does not overflow allocated memory. I have no idea about the details of your string transformation equation - I leave that detail to you. Here is my version below. There is one way to get the input and one way to get the output.

use v5.10; use Inline 'C'; say "At least we have compiled a bit of C code!"; my $output = enctypex_msname("HD2"); say "Output from enctypex_msname() call: $output\n"; =OUTPUT: At least we have compiled a bit of C code! Output from enctypex_msname() call: HD2.ms14.host.com =cut __END__ __C__ unsigned char *enctypex_msname (unsigned char *name) { unsigned char temp[256]; unsigned int c; unsigned char* mover; if(!*name) return(NULL); /* empty string "" */ /* not sure if this will result in undef? +? */ unsigned int server_num = 0; for( mover = name; *mover; mover++) { c = tolower(*mover); server_num = c - (server_num * 0x63306ce7); /*some comment app +ropriate here!!*/ } server_num %= 20; snprintf(temp, sizeof(temp), "%s.ms%d.host.com", name, server_num) +; int length_of_temp_string = strlen(temp)+1; char* ret_buf = (char*)malloc(length_of_temp_string); //could just + allocate 256, so what? if (!ret_buf) { perror("malloc"); exit(1); } memcpy(ret_buf, temp, length_of_temp_string); return(ret_buf); }
It is apparent that the malloc'ed memory gets passed as an SV to $output. At that point, I don't know for sure how this works, but Perl would have to be responsible for calling "free()" on that pointer when the memory for $output is not needed anymore.

I didn't allocate more memory than needed, but that detail doesn't matter much. What does matter is not "re-using memory in a way that is opaque to the user". That is what your version with "static" would do. I recommend against that.

Update: Geez, I am updating a lot tonight. My brain is working on a different project at the moment...But the thought does occur that I don't see anything in this code that would warrant a C subroutine (there is no performance issue). If you explain more about the string transformation algorithm, I am confident that this could be written in native Perl code. In my testing, it does take some extra time to invoke the C compiler and any generated messages are a bit harder to understand than it would be with a native C program. A "pure Perl" implementation would start faster and run time would make no difference. But I get it that you are playing with various options of passing parameters and getting results.

Well as I continue to learn...Update...it is not necessary to do this malloc() stuff...it is possible to create/allocate memory for a new SV string object in one C statement as shown below. This stuff is complex. To say the least!

use v5.10; use Inline 'C'; say "At least we have compiled a bit of C code!"; my $output = enctypex_msname("HD2"); say "Output from enctypex_msname() call: $output\n"; =OUTPUT: At least we have compiled a bit of C code! Output from enctypex_msname() call: HD2.ms14.host.com =cut __END__ __C__ SV *enctypex_msname (unsigned char *name) { unsigned int c; unsigned char* mover; if(!*name) return(NULL); /* empty string "" */ /* not sure if this will result in undef? +? */ unsigned int server_num = 0; for( mover = name; *mover; mover++) { c = tolower(*mover); server_num = c - (server_num * 0x63306ce7); /*some comment app +ropriate here!!*/ } server_num %= 20; return (newSVpvf("%s.ms%d.host.com", name, server_num)); // mall +oc is here... // temp + allocation here too }

In reply to Re: Inline::C and NULL pointers by Marshall
in thread Inline::C and NULL pointers by markong

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (5)
As of 2024-04-18 02:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found