Initializing variable as NULL

Started by pjot, August 20, 2004, 06:54:29 AM

Previous topic - Next topic

pjot

Hi,



In would like to pass a NULL to a C-program. For example, if the C-program looks like this:



------------------

char *txt;

txt = NULL;



function(txt)

------------------



Now, I want to pass the 'txt' variable from newLisp to the C-program.



First I thought I do something like:



(address var)



...but then the C-program crashes when I pass the 'var'.



Then I did:



(set 'var 0)

(address var)



...but now the C-program seems to think I point to an address containing a '0'.



Is there a way to do pass a NULL from newLisp to a C program?



Peter

Lutz

#1
pass a 0 (zero),  just like you did. If the 'C' functions takes a 'char*' it will receive a NULL, have done this many times. Try the following:



(import "/urs/lib/libc.so.4" "printf") ;; on Free BSD 4.7



(printf ">>%s<< %dn" 0 123) =>

>>(null)<<  123

15



it behaves just like a C-program would, indicating that you passed NULL-pointer. The '15' at the end is the return value from 'printf' 15 characters printed.



If your 'C' programs crashes, it must have another reason: does your 'C' programs check for the NULL value? Which platform are you on? From a Win32 newLISP yopu should import with the "cdecl' parameter as in:



(import "mylib" "foo" "cdecl")



On Win32 all imports are by default  stdcall and you may have to specify "cdecl". On Linux/UNIX you don't have to, becuase "cdecl" is the default.





Lutz

Lutz

#2
Try this on Linux/UNIX:



#include <stdio.h>
#include <stdlib.h>

int foo(char * ptr)
{
if(ptr == NULL)
        printf("you passed a NULL pointern");
else
        printf(">>>%s<<<", ptr);

return(0);
}

/* eof */

Compile and link library:

    gcc testlib.c -shared -o testlib.so

Check it in newLISP:

    (import "/usr/home/nuevatec/testlib.so" "foo")

    (foo 0) => you passed a NULL pointer

    (foo "hello") => ">>>hello<<<"


I tried this on FreeBSD



Lutz

Lutz

#3
On Win32 with MinGW do the following:



(1) you need testlib.def

LIBRARY    testlib.dll


EXPORTS
    foo            @1 foo




now compile and link:



gcc -c testlib.c -o testlib.o

dllwrap testlib.o --def testlib.def -o testlib.dll -lws2_32



in newLISP:



newLISP v8.1.3 Copyright (c) 2004 Lutz Mueller. All rights reserved.



> (import "testlib.dll" "foo")

foo <67101194>

> (foo 0)

you passed a NULL pointer

0

> (foo "hello")

>>>hello<<<0

> (exit)





Lutz

pjot

#4
Well, indeed I guess it's my program; in Linux it works, but in Windows it crashes. (Hence my post in this Win32 forum.) This may have to do with the 'cdecl' issue.



I will debug my C-program step-by-step and see what happens with the incoming newLisp value.



Thanks a lot for your hints; especially the last program was very illuminating! I'll come back with my results asap.

Lutz

#5
just posted the Win32 solution, parallel to your post, its right before your post.



Lutz

pjot

#6
Your examples work perfectly OK, also passing variables and increase their value for example. Both in Linux and Win32.



But for some reason my C program keeps crashing; it's on my side for sure. The crash only happens with Win32. Comparing my newLisp memory address passing, it's more or less the same address as the address in your example... strange. Annoying!



If I can find out the cause I'll mention it here.



Thanks again.

pjot

#7
I was about to give up (02:00 here) until I accidentily bumped into the solution. For some strange reason the Windows version of my C program needs to have pre-allocated space of a random structure. Any allocation will do. Then passing the variable from newLisp as you have described works. The allocation is not needed in Linux, but why not, I still do not know.



Thanx again for your support.