[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[open-cobol-list] Parameter passing to C-functions
From: |
Martin Ancher Holm |
Subject: |
[open-cobol-list] Parameter passing to C-functions |
Date: |
Thu, 5 Jun 2008 21:53:57 +0200 |
Hi!
I'm having a problem calling C-functions from OpenCobol.
If I make my own C-function then everything works, but when a C-
function with the same signature is in a linked systemlibrary, the
pointers returned are corrupt.
/* ccalltest.h */
#include <stdio.h>
#include <stdlib.h>
typedef struct { int x; } CFAllocatorRef;
typedef struct { int x; } CFStringRef;
CFAllocatorRef CFAllocatorGetDefault(void);
CFStringRef CFStringCreateWithCString(
CFAllocatorRef alloc,
const char *cStr,
int encoding);
/* ccalltest.c */
#include "ccalltest.h"
CFAllocatorRef CFAllocatorGetDefault(void) {
CFAllocatorRef *cfa;
cfa = malloc(sizeof(CFAllocatorRef));
printf("CFAllocatorGetDefault/\n");
cfa->x = 6;
return *cfa;
}
CFStringRef CFStringCreateWithCString(
CFAllocatorRef alloc,
const char *cStr,
int encoding) {
CFStringRef *cfs;
cfs = malloc(sizeof(CFStringRef));
cfs->x = 2;
printf("CFStringCreateWithCString/\n");
printf("cfs.x/%d/\n", cfs->x);
printf("cstr/%s/\n", cStr);
printf("encoding/%d/\n", encoding);
printf("allocator/x/%d/\n", alloc.x);
return *cfs;
}
* tstccall.cbl
IDENTIFICATION DIVISION.
PROGRAM-ID. TSTCCALL.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 CARBON.
03 COREF-ALLOCATOR USAGE POINTER.
03 CONST-1 PIC 9(09) BINARY.
03 NIB-MAIN.
05 NIB-MAIN-VALUE PIC X(04) VALUE 'main'.
05 NIB-MAIN-NULL PIC 9(01) BINARY VALUE ZERO.
03 NIB-MAIN-CFS USAGE POINTER.
PROCEDURE DIVISION.
000-MAIN SECTION.
CALL 'CFAllocatorGetDefault'
RETURNING COREF-ALLOCATOR
DISPLAY 'COREF-ALLOCATOR/' COREF-ALLOCATOR
MOVE 1 TO CONST-1
CALL 'CFStringCreateWithCString' USING
BY VALUE COREF-ALLOCATOR
BY REFERENCE NIB-MAIN
BY VALUE CODEPAGE-MAC-ROMAN
GIVING NIB-MAIN-CFS
DISPLAY 'NIB-MAIN-CFS/' NIB-MAIN-CFS
GOBACK
.
Compiling by:
$ cobc -x tstccall.cbl ccalltest.c -fstatic-call
/var/folders/kt/ktBjHdTB2RaYWU+1Yxvqm++++TI/-Tmp-//cob27094_0.c: In
function ‘TSTCCALL_’:
/var/folders/kt/ktBjHdTB2RaYWU+1Yxvqm++++TI/-Tmp-//cob27094_0.c:115:
warning: assignment makes pointer from integer without a cast
/var/folders/kt/ktBjHdTB2RaYWU+1Yxvqm++++TI/-Tmp-//cob27094_0.c:138:
warning: assignment makes pointer from integer without a cast
Program running:
$ ./tstccall
CFAllocatorGetDefault/
COREF-ALLOCATOR/0000000006
CFStringCreateWithCString/
cfs.x/2/
cstr/main/
encoding/1/
allocator/x/6/
NIB-MAIN-CFS/0000000002
Everything works fine. A struct created in CFAllocatorGetDefault with
the int x is passed on to CFStringCreateWithCString, and the the data
is intact, and I can print the int x.
Ok now it's time to go for the real deal. I'm gonna get rid of my
testfile ccalltest.c, and link to a library, that has the exact same
signature.
( I've made a symbolic link to the library, since the linker expects a
library to be prefixed with 'lib' and postfixed with '.dylib'.
$ ls -l libCoreFoundation.dylib
lrwxr-xr-x 1 ancher ancher 66 5 Jun 19:46 libCoreFoundation.dylib -
> /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation )
Compiling by:
$ cobc -x tstccall.cbl -lCoreFoundation -L. -fstatic-call
/var/folders/kt/ktBjHdTB2RaYWU+1Yxvqm++++TI/-Tmp-//cob27134_0.c: In
function ‘TSTCCALL_’:
/var/folders/kt/ktBjHdTB2RaYWU+1Yxvqm++++TI/-Tmp-//cob27134_0.c:115:
warning: assignment makes pointer from integer without a cast
/var/folders/kt/ktBjHdTB2RaYWU+1Yxvqm++++TI/-Tmp-//cob27134_0.c:138:
warning: assignment makes pointer from integer without a cast
Program running:
$ ./tstccall
COREF-ALLOCATOR/2689348000
Bus error
This failes, as it seem the pointer variable size is too small for the
pointer returned, therefor the program crashes when a wrong pointer is
sent to CFStringCreateWithCString.
I've tried to fix the problem by changing the variable COREF-ALLOCATOR
USAGE POINTER to COREF-ALLOCATOR PIC 9(19) BINARY.
Compiling by:
$ cobc -x tstccall.cbl ccalltest.c -fstatic-call
/var/folders/kt/ktBjHdTB2RaYWU+1Yxvqm++++TI/-Tmp-//cob27235_0.c: In
function ‘TSTCCALL_’:
/var/folders/kt/ktBjHdTB2RaYWU+1Yxvqm++++TI/-Tmp-//cob27235_0.c:139:
warning: assignment makes pointer from integer without a cast
Program running:
$ ./tstccall
CFAllocatorGetDefault/
COREF-ALLOCATOR/000000000000000006
CFStringCreateWithCString/
cfs.x/2/
cstr/(null)/
encoding/8668/
allocator/x/6/
NIB-MAIN-CFS/0000000002
Compiling by:
$ cobc -x tstccall.cbl -lCoreFoundation -L. -fstatic-call
/var/folders/kt/ktBjHdTB2RaYWU+1Yxvqm++++TI/-Tmp-//cob27256_0.c: In
function ‘TSTCCALL_’:
/var/folders/kt/ktBjHdTB2RaYWU+1Yxvqm++++TI/-Tmp-//cob27256_0.c:139:
warning: assignment makes pointer from integer without a cast
Program running:
$ ./tstccall
COREF-ALLOCATOR/000000001605619296
Bus error
This did not solve the problem, and now even my own testdriver failes
as well.
One interesting thing though is that the pointer returned is 10
digits, and thus too small for the 9 digits reserved for the USAGE
POINTER in OpenCobol.
To me it seems the that the C-api in OpenCobol works as long as the
operating system does NOT return pointers larger than 9 digits.
Yours faithfully
Martin Ancher Holm
- [open-cobol-list] Parameter passing to C-functions,
Martin Ancher Holm <=