473,587 Members | 2,479 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Overloaded vendor library routine: is this C++? Or very clever C?

I've inherited some code which uses an undocumented feature of a
third-party vendor's library. Essentially, this vendor has kept the
details of an interface struct secret, but we can pass a pointer to
this struct to other vendor routines. The struct describes a complex
time-varying object, but it basically boils down to an integer, and
there are access routines to get to the current value of this integer.

My problem is:

1) Our code is C, and the vendor's library is, I think, also C

2) This undocumented feature allowed my (ex) colleague's code to read
the integer directly from the pointer. In other words, the return
value is somehow overloaded.

How is this possible? My only thought is that the vendor library is
actually C++, but even if it is, I still can't see how to make this
work.

Here's a test program that shows this (it compiles Ok as a stand-alone
routine):

#include <stdio.h>

typedef struct dummyTag * dummy; // secret vendor struct

extern dummy bar(void); // vendor's access routine

void foo(void) {
int wibble;
wibble = (long)bar(); // shouldn't be possible, but...
printf("wibble is %d\n", wibble); // works!!
}

Is this possible in C? Or does the vendor library have to be C++? If
it is C++, how does this work? I'm compiling with gcc and I can't see
how this module could interface with a C++ class with overloaded
access routines.

Many thanks -

Jack

May 14 '06 #1
12 2191
[Followups set to comp.lang.c]

Jack Daly said:
I've inherited some code which uses an undocumented feature of a
third-party vendor's library. Essentially, this vendor has kept the
details of an interface struct secret, but we can pass a pointer to
this struct to other vendor routines. The struct describes a complex
time-varying object, but it basically boils down to an integer, and
there are access routines to get to the current value of this integer.
In short, you have an opaque type. So far so good.
My problem is:

1) Our code is C, and the vendor's library is, I think, also C
That's not a problem. That's an opportunity. :-)
2) This undocumented feature allowed my (ex) colleague's code to read
the integer directly from the pointer. In other words, the return
value is somehow overloaded.
Well, perhaps there is a simpler explanation.

How is this possible? My only thought is that the vendor library is
actually C++, but even if it is, I still can't see how to make this
work.

Here's a test program that shows this (it compiles Ok as a stand-alone
routine):

#include <stdio.h>

typedef struct dummyTag * dummy; // secret vendor struct

extern dummy bar(void); // vendor's access routine

void foo(void) {
int wibble;
wibble = (long)bar(); // shouldn't be possible, but...
printf("wibble is %d\n", wibble); // works!!
Well, what you've done is converted a pointer into an integer, which is
legal if you cast it. The resulting information is normally pretty
meaningless, but you seem to think there is meaning in the value you get.
What makes you think that?

If that really is the value that the secret struct stores, then presumably
it's written something like this:

dummy bar(void)
{
return (dummy)secretnu mber;
}
}

Is this possible in C?


I don't think you've yet established that overloading is occurring.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 14 '06 #2
Jack Daly wrote:

I've inherited some code which uses an undocumented feature of a
third-party vendor's library. Essentially, this vendor has kept the
details of an interface struct secret, but we can pass a pointer to
this struct to other vendor routines. The struct describes a complex
time-varying object, but it basically boils down to an integer, and
there are access routines to get to the current value of this integer. 2) This undocumented feature allowed my (ex) colleague's code to read
the integer directly from the pointer. In other words, the return
value is somehow overloaded.

How is this possible?


If I had a struct
where I could read an integer directly from a pointer to the struct,
it would mean something different from what you described,
which I snipped.

If you convert the address of a struct
to a pointer to the type of it's first member,
then that result will be a pointer to the first member of the struct.
If that first member were an integer,
then that's what I would mean by being able to access
an integer directly from a pointer to the struct.

I'm reading this crosspost from clc.

--
pete
May 14 '06 #3
On Sun, 14 May 2006 12:47:05 GMT, pete <pf*****@mindsp ring.com> wrote:
If you convert the address of a struct
to a pointer to the type of it's first member,
then that result will be a pointer to the first member of the struct.
If that first member were an integer,
then that's what I would mean by being able to access
an integer directly from a pointer to the struct.
Hmmm.. but the code casts to a long, rather than a long*:
void foo(void) {
int wibble;
wibble = (long)bar(); // shouldn't be possible, but...
printf("wibble is %d\n", wibble); // works!!
}


If this was C, then the printf should be printing an address, but it
actually prints (from memory, for 4 calls) 2, 18, 0, 0, which is
exactly what I'd expect for these 4 VHDL signals, which are two
integers with values 2 and 18, and two booleans with value false.

So, I don't think it can be C, even buggy C. On the other hand, I
don't see how it can be C++, for 2 reasons:

1 - this compilation unit includes nothing which describes the
internals of 'struct dummyTag'. I didn't think this was possible in
C++ - doesn't the compiler need to know, when compiling this file,
that 'struct dummyTag' is a class which can be read to return a long?

2 - I can't see how I can compile with gcc, rather than g++.

Thanks -

Jack
May 14 '06 #4
Jack Daly wrote:
If this was C, then the printf should be printing an address, but it
actually prints (from memory, for 4 calls) 2, 18, 0, 0, which is
exactly what I'd expect for these 4 VHDL signals, which are two
integers with values 2 and 18, and two booleans with value false.

So, I don't think it can be C, even buggy C. On the other hand, I
don't see how it can be C++, for 2 reasons:

1 - this compilation unit includes nothing which describes the
internals of 'struct dummyTag'. I didn't think this was possible in
C++ - doesn't the compiler need to know, when compiling this file,
that 'struct dummyTag' is a class which can be read to return a long?

2 - I can't see how I can compile with gcc, rather than g++.

Thanks -

Jack


I think Richard Heathfield's post (up the thread) is plausible: in bar,
the vendor is c-casting a long to a dummyTag *, which he then passes
back to you.

The vendor is very clearly saying "keep your mitts off of this thing".
You're ex-colleague is very clearly saying "get stuffed, vendor" :o
May 14 '06 #5
Jack Daly <jd****@yahoo.c om> writes:
I've inherited some code which uses an undocumented feature of a
third-party vendor's library. Essentially, this vendor has kept the
details of an interface struct secret, but we can pass a pointer to
this struct to other vendor routines. The struct describes a complex
time-varying object, but it basically boils down to an integer, and
there are access routines to get to the current value of this integer.

My problem is:

1) Our code is C, and the vendor's library is, I think, also C

2) This undocumented feature allowed my (ex) colleague's code to read
the integer directly from the pointer. In other words, the return
value is somehow overloaded.

How is this possible? My only thought is that the vendor library is
actually C++, but even if it is, I still can't see how to make this
work.

Here's a test program that shows this (it compiles Ok as a stand-alone
routine):

#include <stdio.h>

typedef struct dummyTag * dummy; // secret vendor struct

extern dummy bar(void); // vendor's access routine

void foo(void) {
int wibble;
wibble = (long)bar(); // shouldn't be possible, but...
printf("wibble is %d\n", wibble); // works!!
}

Is this possible in C? Or does the vendor library have to be C++? If
it is C++, how does this work? I'm compiling with gcc and I can't see
how this module could interface with a C++ class with overloaded
access routines.


[Followups redirected to comp.lang.c.]

You're assuming that the code might be C++ because you think it's
doing "overloadin g". You've misunderstood the meaning of the term.

Overloading means using the same name for two different functions or
operators. In C++, you can have two different functions both named
"foo", as long as they take different types of arguments. When the
compiler sees a call to foo(), it determines which function to call by
looking at the arguments. Likewise, you can overload operators as
functions; the C++ standard library does this to use the shift
operators "<<" and ">>" for I/O. When the compiler sees
(cout << "hello"), it decides what to do based on the types of the
operands.

None of this is supported in C, and none of this has anything to do
with the code you posted.

The code you posted is simply converting an expression of one type
(dummy, a pointer type) to another type (long). This is perfectly
legal in C (and in C++), but the result won't necessarily be
meaningful.

Another suspicious thing in the code you posted is that the result of
bar() is converted to long, and then assigned to an int. There may or
may not be a good reason to do that.

The function bar() returns a pointer. Possibly the pointer it returns
is obtained by converting an integer value to the pointer type. The
caller then converts from a pointer type back to an integer type.
This is a dangerously non-portable thing to do -- but sometimes
dangerously non-portable code is what's needed to do the job.

It's also possible that the value returned by bar() is a valid pointer
value, to be used only by the vendor's code, and your function foo()
is abusing it by converting it to long and getting a meaningless
result. (If you're determined to do something dangerous, C won't
necessarily stop you.)

If you just want to display the value returned by bar(), you can use
printf's "%p" format:

void foo(void)
{
dummy wibble = bar();
printf("wibble is %p\n", (void*)wibble);
}

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
May 14 '06 #6
On Sun, 14 May 2006 15:24:37 GMT, Howard Gardner <hg******@rawbw .com>
wrote:
Jack Daly wrote: I think Richard Heathfield's post (up the thread) is plausible: in bar,
the vendor is c-casting a long to a dummyTag *, which he then passes
back to you.


Yes, I'm afraid that I missed that. This would be plausible, except
that dummyTag* has real functionality. I can pass a dummyTag* back to
the library to get it to do clever things with the signal. This would
be impossible if it was simply an integer giving the current value of
the signal; it must actually be an object describing a signal.

So, it seems to me that the library is actually C++, and 'bar' has a
copy assignment operator which returns a long. However, the compiler
can't and doesn't know this, so presumably all the magic (or the
error) is in the gnu linker. I wouldn't have expected this to be
possible.

Jack
May 15 '06 #7
On Sun, 14 May 2006 18:36:35 GMT, Keith Thompson <ks***@mib.or g>
wrote:
Jack Daly <jd****@yahoo.c om> writes:
wibble = (long)bar(); // shouldn't be possible, but...
printf("wibble is %d\n", wibble); // works!!
}

Is this possible in C? Or does the vendor library have to be C++? If
it is C++, how does this work? I'm compiling with gcc and I can't see
how this module could interface with a C++ class with overloaded
access routines.
You're assuming that the code might be C++ because you think it's
doing "overloadin g". You've misunderstood the meaning of the term.
Ok, to be more specific: I'm postulating that the vendor has supplied
a C++ library which has (at least) two copy assignment operators:

long operator=(const bar& rhs) {...}
bar* operator=(const bar& rhs) {...}

Somehow, this C code has linked with the C++ library and the
assignment 'wibble = (long)bar()' is using the first operator.
The code you posted is simply converting an expression of one type
(dummy, a pointer type) to another type (long). This is perfectly
legal in C (and in C++), but the result won't necessarily be
meaningful.
But it *is* meaningful... that's the whole problem. The interesting
thing is - *why* is it meaningful?
The function bar() returns a pointer. Possibly the pointer it returns
is obtained by converting an integer value to the pointer type. The
caller then converts from a pointer type back to an integer type.
This is a dangerously non-portable thing to do -- but sometimes
dangerously non-portable code is what's needed to do the job.
See my reply to Howard - I don't think this is possible. The value
returned by the vendor's 'bar' is, in normal circumstances, meant to
be a real object pointer describing a complex signal - you can pass it
back to the vendor's library, and do complicated things with it.
That's how the vendor's docs describe it, and that's how everybody
else uses the library, including my departed colleague, except in
these 4 cases that I'm trying to figure out. I'd ignore it except that
I think there's something to be learnt here.
It's also possible that the value returned by bar() is a valid pointer
value, to be used only by the vendor's code, and your function foo()
is abusing it by converting it to long and getting a meaningless
result.


No, it's getting a real and valid result - see my two previous
replies. There's no chance that the pointer could display as the
expected current value of the signal (the 4 values it's displaying are
2, 18, 0, and 0, which are exactly correct).

Jack
May 15 '06 #8
Jack Daly wrote:
On Sun, 14 May 2006 18:36:35 GMT, Keith Thompson <ks***@mib.or g>
wrote:

Jack Daly <jd****@yahoo.c om> writes:
wibble = (long)bar(); // shouldn't be possible, but...
printf("wibble is %d\n", wibble); // works!!
}

Is this possible in C? Or does the vendor library have to be C++? If
it is C++, how does this work? I'm compiling with gcc and I can't see
how this module could interface with a C++ class with overloaded
access routines.
You're assuming that the code might be C++ because you think it's
doing "overloadin g". You've misunderstood the meaning of the term.

Ok, to be more specific: I'm postulating that the vendor has supplied
a C++ library which has (at least) two copy assignment operators:

long operator=(const bar& rhs) {...}
bar* operator=(const bar& rhs) {...}


That isn't possible in C++ - you can't overload assignment for built in
types. Nor can you overload the type conversion operator for pointers.
Somehow, this C code has linked with the C++ library and the
assignment 'wibble = (long)bar()' is using the first operator.
I'm afraid this isn't possible - C++ doesn't do what you are talking
about anyway, and in any case it would require the compiler, not linker.
The code you posted is simply converting an expression of one type
(dummy, a pointer type) to another type (long). This is perfectly
legal in C (and in C++), but the result won't necessarily be
meaningful.

But it *is* meaningful... that's the whole problem. The interesting
thing is - *why* is it meaningful?


Could the number returned not be an index or key into a table? This is
how, for example, Microsoft's opaque HANDLE pointers work.
The function bar() returns a pointer. Possibly the pointer it returns
is obtained by converting an integer value to the pointer type. The
caller then converts from a pointer type back to an integer type.
This is a dangerously non-portable thing to do -- but sometimes
dangerously non-portable code is what's needed to do the job.

See my reply to Howard - I don't think this is possible. The value
returned by the vendor's 'bar' is, in normal circumstances, meant to
be a real object pointer describing a complex signal - you can pass it
back to the vendor's library, and do complicated things with it.


It need not be a valid pointer for that. What happens if you print out
the pointer value, e.g.
printf("wibble is %p\n", (void*)wibble);
No, it's getting a real and valid result - see my two previous
replies. There's no chance that the pointer could display as the
expected current value of the signal (the 4 values it's displaying are
2, 18, 0, and 0, which are exactly correct).


What do those values represent?

Tom
May 15 '06 #9
Jack Daly <jd****@yahoo.c om> writes:
On Sun, 14 May 2006 18:36:35 GMT, Keith Thompson <ks***@mib.or g>
wrote:
Jack Daly <jd****@yahoo.c om> writes:
wibble = (long)bar(); // shouldn't be possible, but...
printf("wibble is %d\n", wibble); // works!!
}

Is this possible in C? Or does the vendor library have to be C++? If
it is C++, how does this work? I'm compiling with gcc and I can't see
how this module could interface with a C++ class with overloaded
access routines.

You're assuming that the code might be C++ because you think it's
doing "overloadin g". You've misunderstood the meaning of the term.


Ok, to be more specific: I'm postulating that the vendor has supplied
a C++ library which has (at least) two copy assignment operators:

long operator=(const bar& rhs) {...}
bar* operator=(const bar& rhs) {...}

Somehow, this C code has linked with the C++ library and the
assignment 'wibble = (long)bar()' is using the first operator.


There's no need to assume C++ to explain the behavior you're seeing.
C code is perfectly capable of subverting the type system.

Here's a simple C program in which a function returning a pointer can
return either an actual pointer, or an integer converted to a pointer;
the caller knows what to expect based on the argument it passed to it.

#include <stdio.h>
#include <stdlib.h>

void *func(int n)
{
if (n == 0) {
return malloc(100);
}
else {
return (void*)n;
}
}

int main(void)
{
printf("func(0) returns %p\n", func(0));
printf("func(1) returns %d\n", (int)func(1));
return 0;
}

This is ugly, non-portable code that can easily fail if int and void*
are of different sizes -- or even if they're the same size. But it
may be similar to what your library is doing.

Have you tried asking the vendor?

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
May 15 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

19
2496
by: Deniz Bahar | last post by:
Hi, I would like to call one of my functions the exact name as an existing C library function (for example K&R2 exercises asks me to make an atof function). If I don't include the header with the declaration for the C library function (stdlib.h in this case) then define/declare my own function with the same name, am I safe? It seems to work on my compiler, but I wonder if this is portable or even acceptable? thx
4
2437
by: ±èµ¿±Õ | last post by:
Tell me why the symbol "_" use in the Library? For example, char *_itoa( int value, char *string, int radix ); But We use function "itoa(value,string,radix) "only. I want to know the specific reason .
44
2400
by: bahadir.balban | last post by:
Hi, What's the best way to implement an overloaded function in C? For instance if you want to have generic print function for various structures, my implementation would be with a case statement: void print_structs(void * struct_argument, enum struct_type stype) { switch(stype) { case STRUCT_TYPE_1:
0
1123
by: Evelyne | last post by:
1. my vendor interface is defined in an h & c file: _EXTERN S16BIT _DECL aceSetIrqConditions(S16BIT DevNum, U16BIT bEnable, U32BIT dwIrqMask,void(_DECL *funcExternalIsr)(S16BIT DevNum, U32BIT dwIrqStatus)) void _DECL Callback(S16BIT DevNum, U32BIT dwIrqStatus); /* Configure user callback ISR and enable EOM interrupts */ aceSetIrqConditions(DevNum, TRUE, ACE_IMR1_BC_MSG_EOM, Callback);
15
2037
by: xargon | last post by:
Hi everyone, I am writing a small user interface library in C++ (I know it has been done to death, but it is good for learning ). Anyways, I need some help/advice with the deisgn of the software architecture. The problem I am facing is that a control can have so many states... For example, a button could be have various shapes (rounded, square, some other custom geometry). Also, it could be bitmapped, textured, text only, text with...
12
2614
by: Letsee++ | last post by:
hi, is it possible to write a program to read and print a number without using standard library functions in C and C++? if yes ....how? waiting for a reply...
14
414
by: Jack Daly | last post by:
I've inherited some code which uses an undocumented feature of a third-party vendor's library. Essentially, this vendor has kept the details of an interface struct secret, but we can pass a pointer to this struct to other vendor routines. The struct describes a complex time-varying object, but it basically boils down to an integer, and there are access routines to get to the current value of this integer. My problem is: 1) Our code is...
3
1665
by: mrbrightsidestolemymoney | last post by:
Hi, I need to write out a 1d array of 2d arrays (the structures for each are custom, a 3d structure is defined but not suitable for my use for a number of reasons). Templated routines exist for writing out multi2d<T> and multi1d<T>, hence writing multi2d<multi1d<T>> is possible, although fails for some unknown reason. There is a multi3d<T> writer, but like I said...
24
2176
by: Aaron Gray | last post by:
From what I have been looking at for Javascript library development, browsers that support Javascript 1.5/ECMAScript 3/JScript 5.5 looks like the base level to pitch at. Anyone add anything ? Aaron
0
7923
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8216
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8349
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8221
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6629
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
5719
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
1
2364
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1455
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1192
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.