Recent

Author Topic: Build my own library using xcode to use it with Lazarus  (Read 6485 times)

sinfoni

  • Jr. Member
  • **
  • Posts: 56
Build my own library using xcode to use it with Lazarus
« on: May 27, 2010, 02:20:18 am »
Hi all,

I have to use a very complex structure (kinfo_proc) to do very simple task (killing a process). As converting the C struct to pascal is very tough while I only need two fields (process PID et process name), I'm trying do build a kind of C library in order to call it from my Pascal program.

Here is C code:

Code: [Select]
#include <assert.h>
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/sysctl.h>



typedef struct  {
pid_t p_pid; /* Process identifier. */
char p_comm[128]; // Normalement, MAXCOMLEN+1. Mais comme MAXCOMLEN introuvable.... Fixé à 128 pour faire pareil en Pascal
} procsimple;                                                                                 
typedef struct kinfo_proc kinfo_proc;


static int GetBSDProcessList(kinfo_proc **procList, size_t *procCount)
// Returns a list of all BSD processes on the system.  This routine
// allocates the list and puts it in *procList and a count of the
// number of entries in *procCount.  You are responsible for freeing
// this list (use "free" from System framework).
// On success, the function returns 0.
// On error, the function returns a BSD errno value.
{
    int                 err;
    kinfo_proc *        result;
    bool                done;
    static const int    name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
    // Declaring name as const requires us to cast it when passing it to
    // sysctl because the prototype doesn't include the const modifier.
    size_t              length;

    assert( procList != NULL);
    assert(*procList == NULL);
    assert(procCount != NULL);

    *procCount = 0;

    // We start by calling sysctl with result == NULL and length == 0.
    // That will succeed, and set length to the appropriate length.
    // We then allocate a buffer of that size and call sysctl again
    // with that buffer.  If that succeeds, we're done.  If that fails
    // with ENOMEM, we have to throw away our buffer and loop.  Note
    // that the loop causes use to call sysctl with NULL again; this
    // is necessary because the ENOMEM failure case sets length to
    // the amount of data returned, not the amount of data that
    // could have been returned.

    result = NULL;
    done = false;
    do {
        assert(result == NULL);

        // Call sysctl with a NULL buffer.

        length = 0;
        err = sysctl( (int *) name, (sizeof(name) / sizeof(*name)) - 1,
NULL, &length,
NULL, 0);
        if (err == -1) {
            err = errno;
        }

        // Allocate an appropriately sized buffer based on the results
        // from the previous call.

        if (err == 0) {
            result = malloc(length);
            if (result == NULL) {
                err = ENOMEM;
            }
        }

        // Call sysctl again with the new buffer.  If we get an ENOMEM
        // error, toss away our buffer and start again.

        if (err == 0) {
            err = sysctl( (int *) name, (sizeof(name) / sizeof(*name)) - 1,
result, &length,
NULL, 0);
            if (err == -1) {
                err = errno;
            }
            if (err == 0) {
                done = true;
            } else if (err == ENOMEM) {
                assert(result != NULL);
                free(result);
                result = NULL;
                err = 0;
            }
        }
    } while (err == 0 && ! done);

    // Clean up and establish post conditions.

    if (err != 0 && result != NULL) {
        free(result);
        result = NULL;
    }
    *procList = result;
    if (err == 0) {
        *procCount = length / sizeof(kinfo_proc);
    }

    assert( (err == 0) == (*procList != NULL) );

return err;
}

static int GetBSDProcessListSimple(procsimple ** proclistsimple, size_t *procCount)
{
int err, i, j;
kinfo_proc *       process;
size_t             ProcCount;

    err = GetBSDProcessList(&process, &ProcCount);
*proclistsimple = malloc(ProcCount * sizeof(procsimple));
for (i=0; i< ProcCount; i++) {
(*proclistsimple)[i].p_pid = process[i].kp_proc.p_pid;
for (j=0; j<MAXCOMLEN+1; j++) {
(*proclistsimple)[i].p_comm[j] = process[i].kp_proc.p_comm[j];
}
}
free(process);
return err;
};

Here is the way I would to use it in Lazarus:
Code: [Select]
function GetBSDProcessListSimple(proclistsimple: pp_procsimple;  procCount : p_proccount):integer;cdecl;external clib name 'LibMonaLib';
...

The idea is that kinfo_proc is very huge, so I use a C function to copy the informations I need from it to a simpler C struct that I can easily convert in Pascal.

I use XCode to write C code. The question is: What kind of project must I use ? Application ? Framework & Library (Static ? Dynamic ?) ? Application plug-in ? System plu-in ? Other ?

My goal is to get a unix executable file from which I can import my C function.

At this moment, I've tried to use Library (both static and dynamic). But I can't figure out how to get an executable file.

Any idea ?
André. 
« Last Edit: May 27, 2010, 02:32:01 am by sinfoni »

 

TinyPortal © 2005-2018