I have a static library containing some C functions that implicitly use cdecl calling convention. I also have a header file that contains some data types and prototypes for those functions. The function prototype does not explicitly mention cdecl in it.
I have kernel mode driver which needs to link to this static library. If I include the header file and use the functions, I get linking errors since compiler expects those functions to use stdcall calling convention.
I cannot rebuild the static library from the source using the stdcall calling convention as part of the driver build process.
Is there a way to force compiler to handle this case i.e. treat the header file as using cdecl?
Otherwise the only option I have is to modify the header file to explicitly add cdecl in those function prototypes. I don’t like this option though and hence the question.
I’d recommend you assure your static library and driver are compiled with
identical compiler options, it sounds like they’re not. You know there might
be things other than just the function calling conventions that aren’t
matched. Can you tell us a few more details about where the static library
comes from?
If everything is compiled in a consistent environment, isn’t your header (or
body) file broken if it doesn’t declare things cdecl and the body of the
functions does? It just happened to work in other cases because the default
was cdecl.
Jan
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-487416- xxxxx@lists.osr.com] On Behalf Of xxxxx@vmware.com
Sent: Wednesday, December 21, 2011 4:04 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Linking kernel mode driver to static library having cdecl
functions…
Hello,
I have a static library containing some C functions that implicitly use
cdecl
calling convention. I also have a header file that contains some data
types
and prototypes for those functions. The function prototype does not
explicitly mention cdecl in it.
I have kernel mode driver which needs to link to this static library. If I
include
the header file and use the functions, I get linking errors since compiler
expects those functions to use stdcall calling convention.
I cannot rebuild the static library from the source using the stdcall
calling
convention as part of the driver build process.
Is there a way to force compiler to handle this case i.e. treat the header
file
as using cdecl?
Otherwise the only option I have is to modify the header file to
explicitly add
cdecl in those function prototypes. I don’t like this option though and
hence
the question.
Fix your include for the function prototypes, with the Microsoft
compilers having various calling conventions the only safe approach is
to declare functions that can be called external to the module with the
calling convention.
> Hello, > > I have a static library containing some C functions that implicitly use cdecl calling convention. I also have a header file that contains some data types and prototypes for those functions. The function prototype does not explicitly mention cdecl in it. > > I have kernel mode driver which needs to link to this static library. If I include the header file and use the functions, I get linking errors since compiler expects those functions to use stdcall calling convention. > > I cannot rebuild the static library from the source using the stdcall calling convention as part of the driver build process. > > Is there a way to force compiler to handle this case i.e. treat the header file as using cdecl? > > Otherwise the only option I have is to modify the header file to explicitly add cdecl in those function prototypes. I don’t like this option though and hence the question. > > Thanks. > -Prasad
From: “xxxxx@vmware.com” To: Windows System Software Devs Interest List Sent: Wednesday, December 21, 2011 1:03 PM Subject: [ntdev] Linking kernel mode driver to static library having cdecl functions…
Hello,
I have a static library containing some C functions that implicitly use cdecl calling convention. I also have a header file that contains some data types and prototypes for those functions. The function prototype does not explicitly mention cdecl in it.
I have kernel mode driver which needs to link to this static library. If I include the header file and use the functions, I get linking errors since compiler expects those functions to use stdcall calling convention.
I cannot rebuild the static library from the source using the stdcall calling convention as part of the driver build process.
Is there a way to force compiler to handle this case i.e. treat the header file as using cdecl?
Otherwise the only option I have is to modify the header file to explicitly add cdecl in those function prototypes. I don’t like this option though and hence the question.
Jan, neither header nor body explicitly has cdecl in it. The file contains platform agnostic computation only code and compiles on both Linux and Windows and implicitly uses cdecl convention. Many user mode components (Windows and Linux) consume it, however, Windows kernel mode driver is consuming it for the first time. When I include the header file in the driver, it implicitly assumes it to be stdcall and then I get linking errors. Modifying the header and the body to explicitly mention cdecl is not possible due to unrelated non-techincal reasons. Hence the question.
Don, I agree. But it’s not possible due to reasons mentioned earlier. If there is no option, I will have to copy the header to my project and modify it to explicitly mention cdecl and that takes care of it. But, I wanted to see if I can avoid that.
Calin, this probably doesn’t help. I want rest of the driver code to use stdcall except one header for which I want to tell compiler to use cdecl.
Looks like only option I have is to copy the header to my project and explicitly add cdecl to it.
You could (I think) wrap the #include in whatever #pragma it is that lets
you specify /Gd, and then one more #pragma to pop the setting.
I think that might work.
Mm
On Dec 21, 2011 8:54 PM, wrote:
> Thank you all for your responses. > > Jan, neither header nor body explicitly has cdecl in it. The file contains > platform agnostic computation only code and compiles on both Linux and > Windows and implicitly uses cdecl convention. Many user mode components > (Windows and Linux) consume it, however, Windows kernel mode driver is > consuming it for the first time. When I include the header file in the > driver, it implicitly assumes it to be stdcall and then I get linking > errors. Modifying the header and the body to explicitly mention cdecl is > not possible due to unrelated non-techincal reasons. Hence the question. > > Don, I agree. But it’s not possible due to reasons mentioned earlier. If > there is no option, I will have to copy the header to my project and modify > it to explicitly mention cdecl and that takes care of it. But, I wanted to > see if I can avoid that. > > Calin, this probably doesn’t help. I want rest of the driver code to use > stdcall except one header for which I want to tell compiler to use cdecl. > > Looks like only option I have is to copy the header to my project and > explicitly add cdecl to it. > > Thanks. > -Prasad > > > > — > NTDEV is sponsored by OSR > > For our schedule of WDF, WDM, debugging and other seminars visit: > http://www.osr.com/seminars > > To unsubscribe, visit the List Server section of OSR Online at > http://www.osronline.com/page.cfm?name=ListServer >
So let me see if I understand this correctly. You compile the static library
in some environment totally different than a kernel mode WDK build
environment, like say a Visual Studio user mode project, and then you
attempt to link the static library with the driver? If you compile the code
as a kernel-mode static library, things like the default calling convention
should match. Lots of us build kernel-mode static libraries.
You mentioned that modifying the code is not possible; can you tell us WHY
it’s not possible? You have the source, yes? It might be you have to jump
through some organizational hoops to assure the source code is compatible
with the different build environments, which can be easy or hard, depending
on your organization. This is very different from not possible, and may just
be part of the overhead of having cross platform code.
I can easily imagine some reason like, the platform agnostic code has
already been compiled and has passed QA on Linux, and if you change the
sources the testing will be invalidated. If this is the case, I’m sorry to
say your organization needs to reexamine how cross platform code is created.
Currently, the code is NOT cross platform, as it doesn’t build and run
correctly on some platforms, its Linux code you are attempting to port to
Windows, and changes may be required to support Windows.
Different developers write VASTLY different “portable” C code. Portable for
some might mean it compiles on both x86 Linux and ARM Linux. For others, it
means the code compiles across a couple of different compilers and
processors and a number of different platforms.
Or is the scenario that you don’t have the sources, and you only have some
binary library file you expect to link to from your driver?
Jan
Jan, neither header nor body explicitly has cdecl in it. The file contains
platform agnostic computation only code and compiles on both Linux and
Windows and implicitly uses cdecl convention. Many user mode components
(Windows and Linux) consume it, however, Windows kernel mode driver is
consuming it for the first time. When I include the header file in the
driver, it
implicitly assumes it to be stdcall and then I get linking errors.
Modifying the
header and the body to explicitly mention cdecl is not possible due to
unrelated non-techincal reasons. Hence the question.
Gee, to me, doing it write implies it will work well, maintain system stability, and provide minimum issues over the length of the product. It will also provide a code base that can be used to develop software for newer implementations and hardware.
On the other hand, doing something that works means it will work for this particular implementation, and ON LY this implementation, may not work on the 5 boot of the system, not guaranteed to work with ANYTHING else in the system, and in general, after the developer leaves, is a price of crap spaghetti code that no one can understand let alone modify or fix.
Between the two, I choose doing it right every time.
“Jan Bottorff” wrote in message news:xxxxx@ntdev… … > Different developers write VASTLY different “portable” C code. Portable > for > some might mean it compiles on both x86 Linux and ARM Linux. For others, > it > means the code compiles across a couple of different compilers and > processors and a number of different platforms.
Apropos portability… often in Windows function prototypes are declared like this:
retval DECL func(params)
where “DECL” is a macro which specially serves this purpose. It can be stdcall or cdecl or declspec(…), or__attribute(…). This allows to compile the caller in accordance with the library.
Yes some would call it ugly. Also it looks like alternate function calling methods are considered as micro-optimization these days - amd64 has only one calling sequence, and many OSes as well (WInCE for one), even on x86.