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":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.