Unix Programming - 1 global variable cross multiply files

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > March 2004 > 1 global variable cross multiply files





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author 1 global variable cross multiply files
John Smith

2004-03-23, 4:35 am

I'm writing a Win32 library which I will port to linux soon.

This library consist of a global variable which is a pointer. The library
offers API functions that will make it possible for the user manipulate with
this variable. As pseudo code it looks like:

int *pInstance; // <- global

void Init() {pInstance = malloc(..); ...}
void Free() {free(pInstance);}
int *GetInstance() {return pInstance;}

Now the problem is that if you use the library from multiply files such as
exe + more dlls or binary + multiply shared objects then each file will
essentially contain it's own version of the instance. This gives problems
with it's usage because in secondary files the instance will be
uninitialized.

What I want is to invent a way to synchronize the variable. E.g. when you
call GetInstance() and the current instance is uninitialized (e.g. NULL) it
will try to see if there exist another instance.
One way to do this is with environment varibles where the Init() function
publishes the pointer into a env string such as "MYAPI=...address". However
it does not work under Windows for dll files. I didn't try with linux but I
need a portable solution so one problem is one too many.

Do any of you know a way that files can communicate with each other to
exchange information without making it visible to the user? Any solution
such as preprocessor or other will do fine as long as it's not something the
user of the library needs to care about.
What I asking for is basicly how to create shared memory which each module
can access.

Thanks in advance.

-- John



Robert Harris

2004-03-23, 4:35 am

John Smith wrote:
> I'm writing a Win32 library which I will port to linux soon.
>
> This library consist of a global variable which is a pointer. The library
> offers API functions that will make it possible for the user manipulate with
> this variable. As pseudo code it looks like:
>
> int *pInstance; // <- global
>
> void Init() {pInstance = malloc(..); ...}
> void Free() {free(pInstance);}
> int *GetInstance() {return pInstance;}
>
> Now the problem is that if you use the library from multiply files such as
> exe + more dlls or binary + multiply shared objects then each file will
> essentially contain it's own version of the instance. This gives problems
> with it's usage because in secondary files the instance will be
> uninitialized.
>
> What I want is to invent a way to synchronize the variable. E.g. when you
> call GetInstance() and the current instance is uninitialized (e.g. NULL) it
> will try to see if there exist another instance.
> One way to do this is with environment varibles where the Init() function
> publishes the pointer into a env string such as "MYAPI=...address". However
> it does not work under Windows for dll files. I didn't try with linux but I
> need a portable solution so one problem is one too many.
>
> Do any of you know a way that files can communicate with each other to
> exchange information without making it visible to the user? Any solution
> such as preprocessor or other will do fine as long as it's not something the
> user of the library needs to care about.
> What I asking for is basicly how to create shared memory which each module
> can access.
>
> Thanks in advance.
>
> -- John
>

Either:
1. let your processes mmap() a file, or
2. have a server process "own" the value of pInstance
John Smith

2004-03-23, 5:35 am


"Robert Harris" <robertdotfdotharris@blueyonder.co.uk> wrote in message
news:9iT7c.3200$S61.2691@news-binary.blueyonder.co.uk...

> Either:
> 1. let your processes mmap() a file, or
> 2. have a server process "own" the value of pInstance


By server process do you mean a real additional program (yucky solution) or
in-proc server e.g. a thread? The big question is how "clients" would be
able to see if there is a server available and read from it. Sockets and
other network ideas are probably no good as you can't expect users to have
networking installed if the program does not have anything to do with
networking otherwise.
But if I can invent a way that will work using threads then it's probably a
good solution.

-- John


Robert Harris

2004-03-23, 8:38 am

John Smith wrote:
> "Robert Harris" <robertdotfdotharris@blueyonder.co.uk> wrote in message
> news:9iT7c.3200$S61.2691@news-binary.blueyonder.co.uk...
>

[snip]
> By server process do you mean a real additional program (yucky solution) or
> in-proc server e.g. a thread?

Yes, I mean a real additional program. It could run as a daemon (i.e.
always).

The big question is how "clients" would be
> able to see if there is a server available and read from it. Sockets and
> other network ideas are probably no good as you can't expect users to have
> networking installed if the program does not have anything to do with
> networking otherwise.

All (reasonably recent) Unix systems provide some sort of interprocessor
communication and most provide socket APIs. That is different from
networking in the sense of talking to other computers.

> But if I can invent a way that will work using threads then it's probably a
> good solution.

Well, you need to specify more about the system to reach a good design.

Robert
Chuck Dillon

2004-03-23, 10:36 am

John Smith wrote:

> I'm writing a Win32 library which I will port to linux soon.
>
> This library consist of a global variable which is a pointer. The library
> offers API functions that will make it possible for the user manipulate with
> this variable. As pseudo code it looks like:
>
> int *pInstance; // <- global
>
> void Init() {pInstance = malloc(..); ...}
> void Free() {free(pInstance);}
> int *GetInstance() {return pInstance;}
>
> Now the problem is that if you use the library from multiply files such as
> exe + more dlls or binary + multiply shared objects then each file will
> essentially contain it's own version of the instance. This gives problems
> with it's usage because in secondary files the instance will be
> uninitialized.


If I'm understanding what you are trying to explain properly this is
not a problem in the *nix world. If you put the above code in a shared
library and explicitly link the programs and so's that use it then at
run time you will get exactly one copy of the functions and the
"global" pInstance.

Ask a Winders specific group for a solution to your problem in that world.

-- ced

>
> What I want is to invent a way to synchronize the variable. E.g. when you
> call GetInstance() and the current instance is uninitialized (e.g. NULL) it
> will try to see if there exist another instance.
> One way to do this is with environment varibles where the Init() function
> publishes the pointer into a env string such as "MYAPI=...address". However
> it does not work under Windows for dll files. I didn't try with linux but I
> need a portable solution so one problem is one too many.
>
> Do any of you know a way that files can communicate with each other to
> exchange information without making it visible to the user? Any solution
> such as preprocessor or other will do fine as long as it's not something the
> user of the library needs to care about.
> What I asking for is basicly how to create shared memory which each module
> can access.
>
> Thanks in advance.
>
> -- John
>
>
>



--
Chuck Dillon
Senior Software Engineer
NimbleGen Systems Inc.
Robert Harris

2004-03-23, 11:39 am

Chuck Dillon wrote:
> John Smith wrote:
> <snip>
> If I'm understanding what you are trying to explain properly this is not
> a problem in the *nix world. If you put the above code in a shared
> library and explicitly link the programs and so's that use it then at
> run time you will get exactly one copy of the functions and the "global"
> pInstance.

.... you will get one copy of the function but many copies of the global.

Robert
Fletcher Glenn

2004-03-23, 11:39 am



John Smith wrote:
> I'm writing a Win32 library which I will port to linux soon.
>
> This library consist of a global variable which is a pointer. The library
> offers API functions that will make it possible for the user manipulate with
> this variable. As pseudo code it looks like:
>
> int *pInstance; // <- global
>
> void Init() {pInstance = malloc(..); ...}
> void Free() {free(pInstance);}
> int *GetInstance() {return pInstance;}
>
> Now the problem is that if you use the library from multiply files such as
> exe + more dlls or binary + multiply shared objects then each file will
> essentially contain it's own version of the instance. This gives problems
> with it's usage because in secondary files the instance will be
> uninitialized.
>
> What I want is to invent a way to synchronize the variable. E.g. when you
> call GetInstance() and the current instance is uninitialized (e.g. NULL) it
> will try to see if there exist another instance.
> One way to do this is with environment varibles where the Init() function
> publishes the pointer into a env string such as "MYAPI=...address". However
> it does not work under Windows for dll files. I didn't try with linux but I
> need a portable solution so one problem is one too many.
>
> Do any of you know a way that files can communicate with each other to
> exchange information without making it visible to the user? Any solution
> such as preprocessor or other will do fine as long as it's not something the
> user of the library needs to care about.
> What I asking for is basicly how to create shared memory which each module
> can access.
>
> Thanks in advance.
>
> -- John
>
>
>


You want to share a pointer across several programs?? The pointer would
only be meaningful in the context of the program that sets it. All
other programs would not necessarily have the same data at the same
address, nor would that data necessarily be related to what you were
trying to accomplish.

--

Fletcher Glenn


John Smith

2004-03-24, 3:35 am

> You want to share a pointer across several programs?? The pointer would
> only be meaningful in the context of the program that sets it. All
> other programs would not necessarily have the same data at the same
> address, nor would that data necessarily be related to what you were
> trying to accomplish.
>

No, all goes on within the same process. Let me try to make it more clear.
You got a library L which contains a global variable.
Then you got a binary file A and a shared library B. It is assumed that A
makes use of B. You want to call the library code in both A + B so you need
to link L to both A and B when compiling. Making L a shared library from
which A and B can call the api is not an option due to various requirements
thus L needs to be linked to both files. Now if L contains a global variable
then A and B will have each their instance.
Now I finally solved the thing under Windows using a Microsoft specific api.
With environment variables the first function that calls initializes the
global variable "publishes" the address as a environment variable. This
looks like "myvar=<address>". Each time the variable is needed I see if it's
initialized and if not I see if there exist an environment variable. If so I
convert the string with sscanf() into the pointer.
Example:
A initializes L
A calls the instance variable (it's initialized in A)
A calls a function in B
The function in B needs to use the instance variable too but B's instance is
empty. But with the above trick B will get the same value as the one from A
so it will work.
A frees the instance
.... and all is good because with this scheme B does not need to know
anything about A. This is prefered when writing a library because I can't
possibly know how users will actually use the library. Also it can be
extended to a dozen files since none of them needs to know anything about
the other.

My original problem was that putenv() and getenv() did not work properly in
Windows. I havn't had time to test it under linux yet. When you called
putenv() in file A, getenv() in file B would recieve nothing as it should.
The Microsoft specific api worked better though but I fear the same problems
with putenv()/getenv() could go on under linux too.

-- John


Robert Harris

2004-03-24, 7:35 am

John Smith wrote:
<snip>
> thus L needs to be linked to both files. Now if L contains a global variable
> then A and B will have each their instance.

No. A global variable will have only one instance within a process.

Robert
Chuck Dillon

2004-03-24, 10:39 am

Robert Harris wrote:

> Chuck Dillon wrote:
>
>
> ... you will get one copy of the function but many copies of the global.


Huh? How many copies of errno are there in a process?

I'm guessing that I interpretted the OP as referring to one process and
you interpretted the OP to mean multiple processes. In a single
process there is only one copy of pInstance if as the OP's pseudocode
indicates pInstance has global scope.

-- ced

>
> Robert



--
Chuck Dillon
Senior Software Engineer
NimbleGen Systems Inc.
Robert Harris

2004-03-24, 5:23 pm

Chuck Dillon wrote:

> Huh? How many copies of errno are there in a process?

Wait a moment - a global variables is "global" because there is one of
them in a process. errno is not necessarily a global variable; in a
multithread environment it can't be. the GNU C library, for example,
#define's errno as a function.

Robert
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com