Re: C newbie - pass a LDAP handle out to calling routine

2011-11-08 Thread Bernd Oppolzer

Cool, the newer versions of PL/1 support this, too,
when using the BYVALUE keyword on the ENTRY declarations:

DCL CFUNC ENTRY
(BIN FIXED (31) BYVALUE,
 BIN FLOAT (53) BYVALUE,
 POINTER BYVALUE)
RETURNS (BIN FIXED(31));

and then:

DCL X BIN FIXED (31);
DCL Y BIN FLOAT (53);
DCL P POINTER INIT (ADDR(STRUCT));

RC = CFUNC (X, Y, P);

not sure about the syntax, just a guess. Didn't test it.

Kind regards

Bernd



Am 08.11.2011 02:32, schrieb Frank Swarbrick:

FWIW, COBOL can now call by value, if desired.


given:

int cfunc (int x, double x, struct t *p);

do this:
call 'cfunc' using value cobol-fullword cobol-double
reference cobol-structure 


  returning ret-fullword


Frank






--
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO
Search the archives at http://bama.ua.edu/archives/ibm-main.html


Re: C newbie - pass a LDAP handle out to calling routine

2011-11-07 Thread Frank Swarbrick
FWIW, COBOL can now call by value, if desired.


given:

int cfunc (int x, double x, struct t *p);

do this:
call 'cfunc' using value cobol-fullword cobol-double
   reference cobol-structure  

 returning ret-fullword


Frank





From: Bernd Oppolzer bernd.oppol...@t-online.de
To: IBM-MAIN@bama.ua.edu
Sent: Sunday, November 6, 2011 1:10 PM
Subject: Re: C newbie - pass a LDAP handle out to calling routine

When calling C routines from other languages like COBOL or PL/1 (or FORTRAN),
you have to take into account that in C the parameters are passed by value, 
whereas
the other languages pass them by reference, that is, addresses of the 
variables.

The solution is simple: to construct your C routines so that they can be 
called from
other languages, put a star on every parameter, so that C expects pointers 
instead
of values. Of course, when accessing the parameters inside the C functions,
you have to specify the stars, too.

that is:

int cfunc (int *x, double *x, struct type *p, ..);

Furthermore, the result type should be int, so that other languages can read 
the
return code from the C function result.

If the parameter type is pointer, you need two stars, of course (that was your 
point).

Of course, this does not solve all the problems. You have still the issue with 
char strings,
which are in fact vectors of single chars, so there is already a star. And you 
need to
unterstand that when passing vectors as parameter, you normally pass the 
starting address.

And, with languages like PL/1, you have the locator/descriptor problem. But 
that's
another topic and has nothing to do with C.

Kind regards

Bernd



Am 06.11.2011 20:08, schrieb Gibney, Dave:
 With the assistance of several folks over on MVS-OE, I solved my problem. It 
 is clear here that I did fail in the original question to be clear enough 
 that my driving program is not C. The whole intent was to be able to pass 
 that address from ldap_init back out to the non C driver so that it could be 
 reused by the thousands of calls. The solution was: extern int ret2nat (int 
 *back_value, LDAP **ld, char *msg) This pointer to a pointer format allows 
 the fullword in the calling non C program hold the LDAP handle from call to 
 call.

--
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO
Search the archives at http://bama.ua.edu/archives/ibm-main.html




--
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO
Search the archives at http://bama.ua.edu/archives/ibm-main.html


Re: C newbie - pass a LDAP handle out to calling routine

2011-11-06 Thread Bill Godfrey
On Fri, 4 Nov 2011 21:39:43 +, 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 4GL) 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:46The indirection operator cannot be applied 
to a pointer to an incomplete struct or union.
Or
WARNING CCN3068 /u/ldap/test.c:46Operation 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 lists...@bama.ua.edu with the message: GET IBM-MAIN INFO
Search the archives at http://bama.ua.edu/archives/ibm-main.html


Re: C newbie - pass a LDAP handle out to calling routine

2011-11-06 Thread Shmuel Metz (Seymour J.)
In 0de6a9840123e547b061ac5b6765c0261c1...@exmb-05.ad.wsu.edu, on
11/04/2011
   at 09:39 PM, Gibney, Dave gib...@wsu.edu said:

This is my first experience with C, but a language is a language
after the 3rd or 4th :)

To some extend, but every language has its quirks.


In 0de6a9840123e547b061ac5b6765c0261c1...@exmb-05.ad.wsu.edu, on
11/04/2011
   at 11:10 PM, Gibney, Dave gib...@wsu.edu said:

I've found the discussion of cast in the FM,

Be aware that what C calls a cast is sometimes a cast and sometimes
just a type alias. Be very careful when overriding the type of a
pointer.
 
-- 
 Shmuel (Seymour J.) Metz, SysProg and JOAT
 ISO position; see http://patriot.net/~shmuel/resume/brief.html 
We don't care. We don't have to care, we're Congress.
(S877: The Shut up and Eat Your spam act of 2003)

--
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO
Search the archives at http://bama.ua.edu/archives/ibm-main.html


Re: C newbie - pass a LDAP handle out to calling routine

2011-11-06 Thread Gibney, Dave
 -Original Message-
 From: IBM Mainframe Discussion List [mailto:IBM-MAIN@bama.ua.edu] On
 Behalf Of Bill Godfrey
 Sent: Sunday, November 06, 2011 7:53 AM
 To: IBM-MAIN@bama.ua.edu
 Subject: Re: C newbie - pass a LDAP handle out to calling routine
 
 On Fri, 4 Nov 2011 21:39:43 +, 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 4GL) 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:46The indirection operator cannot be
 applied to a pointer to an incomplete struct or union.
 Or
 WARNING CCN3068 /u/ldap/test.c:46Operation 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.

With the assistance of several folks over on MVS-OE, I solved my problem. It is 
clear

Re: C newbie - pass a LDAP handle out to calling routine

2011-11-06 Thread Bernd Oppolzer
When calling C routines from other languages like COBOL or PL/1 (or 
FORTRAN),
you have to take into account that in C the parameters are passed by 
value, whereas
the other languages pass them by reference, that is, addresses of the 
variables.


The solution is simple: to construct your C routines so that they can be 
called from
other languages, put a star on every parameter, so that C expects 
pointers instead

of values. Of course, when accessing the parameters inside the C functions,
you have to specify the stars, too.

that is:

int cfunc (int *x, double *x, struct type *p, ..);

Furthermore, the result type should be int, so that other languages can 
read the

return code from the C function result.

If the parameter type is pointer, you need two stars, of course (that 
was your point).


Of course, this does not solve all the problems. You have still the 
issue with char strings,
which are in fact vectors of single chars, so there is already a star. 
And you need to
unterstand that when passing vectors as parameter, you normally pass the 
starting address.


And, with languages like PL/1, you have the locator/descriptor problem. 
But that's

another topic and has nothing to do with C.

Kind regards

Bernd



Am 06.11.2011 20:08, schrieb Gibney, Dave:
With the assistance of several folks over on MVS-OE, I solved my 
problem. It is clear here that I did fail in the original question to 
be clear enough that my driving program is not C. The whole intent was 
to be able to pass that address from ldap_init back out to the non C 
driver so that it could be reused by the thousands of calls. The 
solution was: extern int ret2nat (int *back_value, LDAP **ld, char 
*msg) This pointer to a pointer format allows the fullword in the 
calling non C program hold the LDAP handle from call to call.


--
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO
Search the archives at http://bama.ua.edu/archives/ibm-main.html


Re: C newbie - pass a LDAP handle out to calling routine

2011-11-06 Thread Steve Comstock

On 11/6/2011 1:10 PM, Bernd Oppolzer wrote:

When calling C routines from other languages like COBOL or PL/1 (or FORTRAN),
you have to take into account that in C the parameters are passed by value,
whereas
the other languages pass them by reference, that is, addresses of the 
variables.

The solution is simple: to construct your C routines so that they can be called
from
other languages, put a star on every parameter, so that C expects pointers 
instead
of values. Of course, when accessing the parameters inside the C functions,
you have to specify the stars, too.

that is:

int cfunc (int *x, double *x, struct type *p, ..);

Furthermore, the result type should be int, so that other languages can read the
return code from the C function result.

If the parameter type is pointer, you need two stars, of course (that was your
point).

Of course, this does not solve all the problems. You have still the issue with
char strings,
which are in fact vectors of single chars, so there is already a star. And you
need to
unterstand that when passing vectors as parameter, you normally pass the
starting address.

And, with languages like PL/1, you have the locator/descriptor problem. But 
that's
another topic and has nothing to do with C.

Kind regards

Bernd



ad
 We discuss all these issues, and more, in our 3 day course

 Cross Program Communication in z/OS. Details at:

http://www.trainersfriend.com/Language_Environment_courses/m520descr.htm

 The course covers any mix of these languages that the students want
 to include: Assembler, COBOL, PL/I, and C. Lectures are set and
 labs available for all four languages, and you can focus on just
 one language or any mix you like.

/ad




Am 06.11.2011 20:08, schrieb Gibney, Dave:

With the assistance of several folks over on MVS-OE, I solved my problem. It
is clear here that I did fail in the original question to be clear enough that
my driving program is not C. The whole intent was to be able to pass that
address from ldap_init back out to the non C driver so that it could be reused
by the thousands of calls. The solution was: extern int ret2nat (int
*back_value, LDAP **ld, char *msg) This pointer to a pointer format allows the
fullword in the calling non C program hold the LDAP handle from call to call.


--
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO
Search the archives at http://bama.ua.edu/archives/ibm-main.html




--

Kind regards,

-Steve Comstock
The Trainer's Friend, Inc.

303-393-8716
http://www.trainersfriend.com

* To get a good Return on your Investment, first make an investment!
  + Training your people is an excellent investment

* Try our new tool for calculating your Return On Investment
for training dollars at
  http://www.trainersfriend.com/ROI/roi.html

--
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO
Search the archives at http://bama.ua.edu/archives/ibm-main.html


C newbie - pass a LDAP handle out to calling routine

2011-11-04 Thread Gibney, Dave
  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 4GL) 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:46The indirection operator cannot be applied 
to a pointer to an incomplete struct or union.  
 
Or
WARNING CCN3068 /u/ldap/test.c:46Operation 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

--
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO
Search the archives at http://bama.ua.edu/archives/ibm-main.html


Re: C newbie - pass a LDAP handle out to calling routine

2011-11-04 Thread Don Poitras
Dave,
  You need to cast to a pointer type that memcpy (or whatever) can
handle. e.g.

 memcpy(foo, *((char *) ld), 10);

If you want to use this a lot, it might be better to just copy
to a pointer of another type:

 char *bar;

 bar = (char *) ld;
 memcpy(foo, *bar, 10);

Also, I find it beneficial to display addresses in hex. e.g.

printf(ld before bind   :%08X\n,ld);  

In article 0de6a9840123e547b061ac5b6765c0261c1...@exmb-05.ad.wsu.edu you 
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 4GL) 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:46The indirection operator cannot be applied 
 to a pointer to an incomplete struct or union.
   
  
 Or
 WARNING CCN3068 /u/ldap/test.c:46Operation 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

-- 
Don Poitras - SAS Development  -  SAS Institute Inc. - SAS Campus Drive
sas...@sas.com   (919) 531-5637Cary, NC 27513

--
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO
Search the archives at http://bama.ua.edu/archives/ibm-main.html


Re: C newbie - pass a LDAP handle out to calling routine

2011-11-04 Thread Don Poitras
Sorry, memcpy was a bad example. The parms to that are pointers, not
dereferenced pointers.

 memcpy(foo, ld, 10); 

didn't work? I guess that's something to do with incomplete type.
I'm not familiar with that. My suggestion still sort of stands though.
Try:

 memcpy(foo, (char *) ld, 10);

and for the 2nd example:

 memcpy(foo, bar, 10);

In article 2004225459.dda808f...@panix3.panix.com you wrote:
 Dave,
   You need to cast to a pointer type that memcpy (or whatever) can
 handle. e.g.

  memcpy(foo, *((char *) ld), 10);

 If you want to use this a lot, it might be better to just copy
 to a pointer of another type:

  char *bar;

  bar = (char *) ld;
  memcpy(foo, *bar, 10);

 Also, I find it beneficial to display addresses in hex. e.g.

 printf(ld before bind   :%08X\n,ld);  

 In article 0de6a9840123e547b061ac5b6765c0261c1...@exmb-05.ad.wsu.edu you 
 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 4GL) 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:46The indirection operator cannot be 
  applied to a pointer to an incomplete struct or union.  
  
   
  Or
  WARNING CCN3068 /u/ldap/test.c:46Operation 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

-- 
Don Poitras - SAS Development  -  SAS Institute Inc. - SAS Campus Drive
sas...@sas.com   (919) 531-5637Cary, NC 27513

--
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO
Search the archives at http://bama.ua.edu/archives/ibm-main.html


Re: C newbie - pass a LDAP handle out to calling routine

2011-11-04 Thread Gibney, Dave
First, thanks for the display in hex, that will help me a lot in future C (if 
I'm ever here again after this project)

I've found the discussion of cast in the FM, it is several chapters down from 
where I was in a straight thru read of the Language reference.  It looks like 
this will let me make progress.

I said a language is a language and it's true, but I also know it takes a lot 
of practice to become fluent. I may not see C again for years once I get this 
thing working. I really appreciate the help the listserves can provide/

Dave Gibney
Information Technology Services
Washington State University


 -Original Message-
 From: IBM Mainframe Discussion List [mailto:IBM-MAIN@bama.ua.edu] On
 Behalf Of Don Poitras
 Sent: Friday, November 04, 2011 3:55 PM
 To: IBM-MAIN@bama.ua.edu
 Subject: Re: C newbie - pass a LDAP handle out to calling routine
 
 Dave,
   You need to cast to a pointer type that memcpy (or whatever) can
 handle. e.g.
 
  memcpy(foo, *((char *) ld), 10);
 
 If you want to use this a lot, it might be better to just copy
 to a pointer of another type:
 
  char *bar;
 
  bar = (char *) ld;
  memcpy(foo, *bar, 10);
 
 Also, I find it beneficial to display addresses in hex. e.g.
 
 printf(ld before bind   :%08X\n,ld);
 
 In article 0DE6A9840123E547B061AC5B6765C0261C148A@EXMB-
 05.ad.wsu.edu you 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 4GL) 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:46The indirection operator cannot be
 applied to a pointer to an incomplete struct or union.
  Or
  WARNING CCN3068 /u/ldap/test.c:46Operation 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
 
 --
 Don Poitras - SAS Development  -  SAS Institute Inc. - SAS Campus Drive
 sas...@sas.com   (919) 531-5637Cary, NC 27513
 
 --
 For IBM-MAIN subscribe / signoff / archive access instructions,
 send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO
 Search the archives at http://bama.ua.edu/archives/ibm-main.html

--
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO
Search the archives at http://bama.ua.edu/archives/ibm-main.html


Re: C newbie - pass a LDAP handle out to calling routine

2011-11-04 Thread Charles Mills
Be very, very, very careful with casting. The compiler (usually) knows more
about C than a newbie coder does. If you code foo = bar and the compiler
objects, there is probably a good reason. Coding foo = (FooStruct)bar may
make the compiler error go away but it just trades it for a much harder to
diagnose run-time error.

Charles

-Original Message-
From: IBM Mainframe Discussion List [mailto:IBM-MAIN@bama.ua.edu] On Behalf
Of Gibney, Dave
Sent: Friday, November 04, 2011 4:11 PM
To: IBM-MAIN@bama.ua.edu
Subject: Re: C newbie - pass a LDAP handle out to calling routine

First, thanks for the display in hex, that will help me a lot in future C
(if I'm ever here again after this project)

I've found the discussion of cast in the FM, it is several chapters down
from where I was in a straight thru read of the Language reference.  It
looks like this will let me make progress.

I said a language is a language and it's true, but I also know it takes a
lot of practice to become fluent. I may not see C again for years once I get
this thing working. I really appreciate the help the listserves can provide/

Dave Gibney
Information Technology Services
Washington State University


 -Original Message-
 From: IBM Mainframe Discussion List [mailto:IBM-MAIN@bama.ua.edu] On 
 Behalf Of Don Poitras
 Sent: Friday, November 04, 2011 3:55 PM
 To: IBM-MAIN@bama.ua.edu
 Subject: Re: C newbie - pass a LDAP handle out to calling routine
 
 Dave,
   You need to cast to a pointer type that memcpy (or whatever) can 
 handle. e.g.
 
  memcpy(foo, *((char *) ld), 10);
 
 If you want to use this a lot, it might be better to just copy to a 
 pointer of another type:
 
  char *bar;
 
  bar = (char *) ld;
  memcpy(foo, *bar, 10);
 
 Also, I find it beneficial to display addresses in hex. e.g.
 
 printf(ld before bind   :%08X\n,ld);
 
 In article 0DE6A9840123E547B061AC5B6765C0261C148A@EXMB-
 05.ad.wsu.edu you 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 4GL) 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:46The indirection operator cannot be
 applied to a pointer to an incomplete struct or union.
  Or
  WARNING CCN3068 /u/ldap/test.c:46Operation 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
 
 --
 Don Poitras - SAS Development  -  SAS Institute Inc. - SAS Campus Drive
 sas...@sas.com   (919) 531-5637Cary, NC 27513
 
 --
 For IBM-MAIN subscribe / signoff / archive access instructions, send 
 email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO 
 Search the archives at http://bama.ua.edu/archives/ibm-main.html

--
For IBM-MAIN subscribe / signoff / archive access instructions, send email
to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the
archives at http://bama.ua.edu/archives/ibm-main.html

--
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO
Search the archives at http://bama.ua.edu/archives/ibm-main.html


Re: C newbie - pass a LDAP handle out to calling routine

2011-11-04 Thread Charles Mills
To be totally correct the flag is %p. That will print a pointer in whatever
notation is appropriate to the platform. Of course for z, that format is
08X. Unless it's 64-bit z.

Charles

-Original Message-
From: IBM Mainframe Discussion List [mailto:IBM-MAIN@bama.ua.edu] On Behalf
Of Gibney, Dave
Sent: Friday, November 04, 2011 4:11 PM
To: IBM-MAIN@bama.ua.edu
Subject: Re: C newbie - pass a LDAP handle out to calling routine

First, thanks for the display in hex, that will help me a lot in future C
(if I'm ever here again after this project)

I've found the discussion of cast in the FM, it is several chapters down
from where I was in a straight thru read of the Language reference.  It
looks like this will let me make progress.

I said a language is a language and it's true, but I also know it takes a
lot of practice to become fluent. I may not see C again for years once I get
this thing working. I really appreciate the help the listserves can provide/

Dave Gibney
Information Technology Services
Washington State University


 -Original Message-
 From: IBM Mainframe Discussion List [mailto:IBM-MAIN@bama.ua.edu] On 
 Behalf Of Don Poitras
 Sent: Friday, November 04, 2011 3:55 PM
 To: IBM-MAIN@bama.ua.edu
 Subject: Re: C newbie - pass a LDAP handle out to calling routine
 
 Dave,
   You need to cast to a pointer type that memcpy (or whatever) can 
 handle. e.g.
 
  memcpy(foo, *((char *) ld), 10);
 
 If you want to use this a lot, it might be better to just copy to a 
 pointer of another type:
 
  char *bar;
 
  bar = (char *) ld;
  memcpy(foo, *bar, 10);
 
 Also, I find it beneficial to display addresses in hex. e.g.
 
 printf(ld before bind   :%08X\n,ld);
 
 In article 0DE6A9840123E547B061AC5B6765C0261C148A@EXMB-
 05.ad.wsu.edu you 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 4GL) 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:46The indirection operator cannot be
 applied to a pointer to an incomplete struct or union.
  Or
  WARNING CCN3068 /u/ldap/test.c:46Operation 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
 
 --
 Don Poitras - SAS Development  -  SAS Institute Inc. - SAS Campus Drive
 sas...@sas.com   (919) 531-5637Cary, NC 27513
 
 --
 For IBM-MAIN subscribe / signoff / archive access instructions, send 
 email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO 
 Search the archives at http://bama.ua.edu/archives/ibm-main.html

--
For IBM-MAIN subscribe / signoff / archive access instructions, send email
to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the
archives at http://bama.ua.edu/archives/ibm-main.html

--
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO
Search the archives at http://bama.ua.edu/archives/ibm-main.html