On Fri, 4 Nov 2011 21:39:43 +0000, Dave Gibney wrote:
> This is my first experience with C, but a language is a language after the
> 3rd or 4th :)
>I'm calling C for LDAP queries from Natural (Software AG "4"GL) in batch. And
>it works, sort of.
>One FM is IBM Tivoli Directory Server Client Programming for z/OS
>
> If I use the sequence ldap_init, ldap_simple_bind_s, ldap_search,
> ldap_unbind, it gets overloaded after 5 calls at the speed of batch. If I
> leave out the unbind, it works for thousands of calls, but there is an
> obvious memory leak.
> So, I want to anchor the ldap handle in the main driving program. I made a
> simple C stub:
>
>extern int ret2nat (int *back_value, LDAP *ld, char *msg)
>#include <ldap.h>
>
>In ldap.h there is:
>typedef struct ldap LDAP;
>
>The examples use:
>LDAP * ld;
>To declare an ldap_handle which according to the listing is an:
>ld 6270-1:1931 Class = parameter, Length = 4
> Type = pointer to incomplete struct ldap
>
>I have a function:
>LDAP * bind_adlds(char *hostname, char *container, char *msg)
>And I call it:
>printf("ld before bind :%d\n",ld); /* ld before bind :286352012
>ld = bind_adlds(hostname, container, msg) ;
>printf("ld after bind :%d\n",ld); /* ld after bind :283317144
>
>but the value is not returned to the caller of ret2nat.
>
>Any attempts to use *ld in an assignment or even memcpy() get a complier
>message:
>ERROR CCN3285 /u/ldap/test.c:46 The indirection operator cannot be applied
>to a pointer to an incomplete struct or union.
>Or
>WARNING CCN3068 /u/ldap/test.c:46 Operation between types "int*" and
>"pointer to an incomplete type" is not allowed.
>
>As I said, I am just learning how to spell C. I know I am fighting some kind
>of battle of types. I welcome even derisive comments, if in the end thay help.
>
>Dave Gibney
>Information Technology Services
>Washington State University
>
I'm not sure I understand the design of your program. You seem to have a "main
driver" program, and an int function named "ret2nat" which accepts an LDAP * as
one of its arguments, and a "bind_adlds" function which sets the value of an
LDAP *. But I don't follow how the sequence of function calls are supposed to
work. Maybe what I have to say will cause you to redo the design.
What you call a "stub" might be the first statement in a function, or a
function prototype without the trailing semicolon, I'm not sure which. I don't
think the "extern" is needed for functions.
This statement, which I presume is in your "main driver" program,
LDAP * ld;
defines a pointer to an LDAP structure, but initially it does not point to
anything. It does not put an LDAP structure in your main program. Its value is
meaningless until the ldap_init function has filled in the pointer with the
address of the LDAP structure, which is in memory obtained by ldap_init. There
is no way to tell ldap_init to use any other memory for the LDAP structure. If
you call ldap_init more than once with the same pointer as the returned value,
without calling ldap_unbind to free the memory, ldap_init will replace the
address in that pointer with a new address of another LDAP structure, and you
will have no way to free the memory used by the first LDAP structure. (Well,
you could save a copy of the pointer first, but when would you intend to use
that copy and free the memory?) That's probably the "obvious memory leak" you
referred to. I'm not sure if you already understand that, or if this is new
information to you.
I don't understand why your program would ever need to use *ld in an assignment
or in memcpy(). Perhaps you are mistaken in even attempting to do that, in
which case there is no point in trying to make the assignment work.
You mentioned "thousands of calls". If this statement:
ld = bind_adlds(hostname, container, msg) ;
is the one that will run thousands of times, I see a problem with that. You
probably don't want to change pointer ld thousands of times, especially without
intervening calls to ldap_unbind. If all of the ldap_search calls are for the
same hostname, you should assign a value to ld one time, using ldap_init or a
function of your own that uses ldap_init, and perhaps also call
ldap_simple-bind one time, and then, for the thousands of calls, call a
different function that takes ld as an argument to perform the lap_search.
Lastly, call ldap_unbind to free the LDAP structure.
If this is giving you a better understanding of the functions, perhaps you will
decide to reconsider your design. Or maybe I am misunderstanding what you said.
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: GET IBM-MAIN INFO
Search the archives at http://bama.ua.edu/archives/ibm-main.html