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

Reply via email to