473,406 Members | 2,343 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

OS dependend DllImport

I'm trying to make a sort of conditional compilation in my C# code because
my app is intended to run on both a Pocket PC and on a normal desktop PC. My
code uses a call to an API function that on the PPC is located in
coredll.dll and on the desktop in kernel32.dll. I could make two versions of
the DllImported funktions but then I would have to ask for the OS version in
every call to the function. This however causes the code to look messy and
it does also make the code a lot slower in case of intensive calls to the
funktion like e.g. reading single bytes from a serial port running at a
speed of 115k. A code like this would be perfect:
#if (System.Environment.OSVersion.Platform == PlatformID.WinCE)
[DllImport("coredll.dll", EntryPoint="ReadFile", SetLastError=true)]
#else
[DllImport("coredll.dll", EntryPoint="ReadFile", SetLastError=true)]
#endif
private static extern bool ReadFile(......

But it is unfortunately not possible because the
"System.Environment.OSVersion.Platform == PlatformID.WinCE" is a not legal
argument to #if in C#. Another similar solution could be:
if (System.Environment.OSVersion.Platform == PlatformID.WinCE)
{
[DllImport("coredll.dll", EntryPoint="ReadFile", SetLastError=true)]
}
else
{
[DllImport("coredll.dll", EntryPoint="ReadFile", SetLastError=true)]
}
private static extern bool ReadFile(......

But this is unfortunately not legal either, because C# doesn't accept that
the dllImport statement is located in a funktion like e.g. form_load.

Does anyone have any idea to do this in a clever way?

Thanks a lot!
Ole
Nov 16 '05 #1
9 4935
Sorry: The "coredll.dll" must be replaced with "kernel32.dll" in the else
sentences below.
Ole
I'm trying to make a sort of conditional compilation in my C# code because
my app is intended to run on both a Pocket PC and on a normal desktop PC. My code uses a call to an API function that on the PPC is located in
coredll.dll and on the desktop in kernel32.dll. I could make two versions of the DllImported funktions but then I would have to ask for the OS version in every call to the function. This however causes the code to look messy and
it does also make the code a lot slower in case of intensive calls to the
funktion like e.g. reading single bytes from a serial port running at a
speed of 115k. A code like this would be perfect:
#if (System.Environment.OSVersion.Platform == PlatformID.WinCE)
[DllImport("coredll.dll", EntryPoint="ReadFile", SetLastError=true)] #else
[DllImport("coredll.dll", EntryPoint="ReadFile", SetLastError=true)] #endif
private static extern bool ReadFile(......

But it is unfortunately not possible because the
"System.Environment.OSVersion.Platform == PlatformID.WinCE" is a not legal
argument to #if in C#. Another similar solution could be:
if (System.Environment.OSVersion.Platform == PlatformID.WinCE)
{
[DllImport("coredll.dll", EntryPoint="ReadFile", SetLastError=true)] }
else
{
[DllImport("coredll.dll", EntryPoint="ReadFile", SetLastError=true)] }
private static extern bool ReadFile(......

But this is unfortunately not legal either, because C# doesn't accept that
the dllImport statement is located in a funktion like e.g. form_load.

Does anyone have any idea to do this in a clever way?

Thanks a lot!
Ole

Nov 16 '05 #2
Ole,

I would define a flag, POCKET_PC or something like that, and then do the
following:

[DllImport(

// If pocket PC is defined, then compile against coredll.dll.
#if POCKET_PC
"coredll.dll"
#else
"kernel32.dll"
#endif
, EntryPoint="ReadFile", SetLastError=true)]
private static extern bool ReadFile(...

However, this can get pretty messy. I would recommend you do the
definition like this:

[DllImport(Win32DllAlias.Kernel32, EntryPoint="ReadFile",
SetLastError=true)]
public static extern bool ReadFile(...

And then define a dll that has constants in it, exposing the dll name.
Of course, it is there where you place the condition for your constant:

#if POCKET_PC
public const string Kernel32 = "kernel32.dll";
#else
public const string Kernel32 = "coredll.dll";
#endif

This is the cleaner solution, IMO.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Ole Christensen" <or*@sol.dk> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
I'm trying to make a sort of conditional compilation in my C# code because
my app is intended to run on both a Pocket PC and on a normal desktop PC.
My
code uses a call to an API function that on the PPC is located in
coredll.dll and on the desktop in kernel32.dll. I could make two versions
of
the DllImported funktions but then I would have to ask for the OS version
in
every call to the function. This however causes the code to look messy and
it does also make the code a lot slower in case of intensive calls to the
funktion like e.g. reading single bytes from a serial port running at a
speed of 115k. A code like this would be perfect:
#if (System.Environment.OSVersion.Platform == PlatformID.WinCE)
[DllImport("coredll.dll", EntryPoint="ReadFile",
SetLastError=true)]
#else
[DllImport("coredll.dll", EntryPoint="ReadFile",
SetLastError=true)]
#endif
private static extern bool ReadFile(......

But it is unfortunately not possible because the
"System.Environment.OSVersion.Platform == PlatformID.WinCE" is a not legal
argument to #if in C#. Another similar solution could be:
if (System.Environment.OSVersion.Platform == PlatformID.WinCE)
{
[DllImport("coredll.dll", EntryPoint="ReadFile", SetLastError=true)]
}
else
{
[DllImport("coredll.dll", EntryPoint="ReadFile",
SetLastError=true)]
}
private static extern bool ReadFile(......

But this is unfortunately not legal either, because C# doesn't accept that
the dllImport statement is located in a funktion like e.g. form_load.

Does anyone have any idea to do this in a clever way?

Thanks a lot!
Ole

Nov 16 '05 #3
Hi Nicholas,

Thank you for your promt respons!

Defining a flag would make my code OS dependend. If I didn't have to do the
DllImport I would be able to simply move the exe file from the Pocket PC to
the Desktop PC and run it there instead, but defining a flag would destroy
that possibility.

Thanks,
Ole

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in
message news:eG**************@TK2MSFTNGP12.phx.gbl...
Ole,

I would define a flag, POCKET_PC or something like that, and then do the following:

[DllImport(

// If pocket PC is defined, then compile against coredll.dll.
#if POCKET_PC
"coredll.dll"
#else
"kernel32.dll"
#endif
, EntryPoint="ReadFile", SetLastError=true)]
private static extern bool ReadFile(...

However, this can get pretty messy. I would recommend you do the
definition like this:

[DllImport(Win32DllAlias.Kernel32, EntryPoint="ReadFile",
SetLastError=true)]
public static extern bool ReadFile(...

And then define a dll that has constants in it, exposing the dll name.
Of course, it is there where you place the condition for your constant:

#if POCKET_PC
public const string Kernel32 = "kernel32.dll";
#else
public const string Kernel32 = "coredll.dll";
#endif

This is the cleaner solution, IMO.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Ole Christensen" <or*@sol.dk> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
I'm trying to make a sort of conditional compilation in my C# code because my app is intended to run on both a Pocket PC and on a normal desktop PC. My
code uses a call to an API function that on the PPC is located in
coredll.dll and on the desktop in kernel32.dll. I could make two versions of
the DllImported funktions but then I would have to ask for the OS version in
every call to the function. This however causes the code to look messy and it does also make the code a lot slower in case of intensive calls to the funktion like e.g. reading single bytes from a serial port running at a
speed of 115k. A code like this would be perfect:
#if (System.Environment.OSVersion.Platform == PlatformID.WinCE)
[DllImport("coredll.dll", EntryPoint="ReadFile",
SetLastError=true)]
#else
[DllImport("coredll.dll", EntryPoint="ReadFile",
SetLastError=true)]
#endif
private static extern bool ReadFile(......

But it is unfortunately not possible because the
"System.Environment.OSVersion.Platform == PlatformID.WinCE" is a not legal argument to #if in C#. Another similar solution could be:
if (System.Environment.OSVersion.Platform == PlatformID.WinCE)
{
[DllImport("coredll.dll", EntryPoint="ReadFile", SetLastError=true)] }
else
{
[DllImport("coredll.dll", EntryPoint="ReadFile",
SetLastError=true)]
}
private static extern bool ReadFile(......

But this is unfortunately not legal either, because C# doesn't accept that the dllImport statement is located in a funktion like e.g. form_load.

Does anyone have any idea to do this in a clever way?

Thanks a lot!
Ole


Nov 16 '05 #4
Ole,

Because of what you are doing though, you have no other choice. The
only other option would be to wrap all of your API calls in one separate
assembly, and then have that single assembly be OS dependent.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Ole Christensen" <or*@sol.dk> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Hi Nicholas,

Thank you for your promt respons!

Defining a flag would make my code OS dependend. If I didn't have to do
the
DllImport I would be able to simply move the exe file from the Pocket PC
to
the Desktop PC and run it there instead, but defining a flag would destroy
that possibility.

Thanks,
Ole

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote
in
message news:eG**************@TK2MSFTNGP12.phx.gbl...
Ole,

I would define a flag, POCKET_PC or something like that, and then do

the
following:

[DllImport(

// If pocket PC is defined, then compile against coredll.dll.
#if POCKET_PC
"coredll.dll"
#else
"kernel32.dll"
#endif
, EntryPoint="ReadFile", SetLastError=true)]
private static extern bool ReadFile(...

However, this can get pretty messy. I would recommend you do the
definition like this:

[DllImport(Win32DllAlias.Kernel32, EntryPoint="ReadFile",
SetLastError=true)]
public static extern bool ReadFile(...

And then define a dll that has constants in it, exposing the dll
name.
Of course, it is there where you place the condition for your constant:

#if POCKET_PC
public const string Kernel32 = "kernel32.dll";
#else
public const string Kernel32 = "coredll.dll";
#endif

This is the cleaner solution, IMO.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Ole Christensen" <or*@sol.dk> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
> I'm trying to make a sort of conditional compilation in my C# code because > my app is intended to run on both a Pocket PC and on a normal desktop PC. > My
> code uses a call to an API function that on the PPC is located in
> coredll.dll and on the desktop in kernel32.dll. I could make two versions > of
> the DllImported funktions but then I would have to ask for the OS version > in
> every call to the function. This however causes the code to look messy and > it does also make the code a lot slower in case of intensive calls to the > funktion like e.g. reading single bytes from a serial port running at a
> speed of 115k. A code like this would be perfect:
> #if (System.Environment.OSVersion.Platform == PlatformID.WinCE)
> [DllImport("coredll.dll", EntryPoint="ReadFile",
> SetLastError=true)]
> #else
> [DllImport("coredll.dll", EntryPoint="ReadFile",
> SetLastError=true)]
> #endif
> private static extern bool ReadFile(......
>
> But it is unfortunately not possible because the
> "System.Environment.OSVersion.Platform == PlatformID.WinCE" is a not legal > argument to #if in C#. Another similar solution could be:
> if (System.Environment.OSVersion.Platform == PlatformID.WinCE)
> {
> [DllImport("coredll.dll", EntryPoint="ReadFile", SetLastError=true)] > }
> else
> {
> [DllImport("coredll.dll", EntryPoint="ReadFile",
> SetLastError=true)]
> }
> private static extern bool ReadFile(......
>
> But this is unfortunately not legal either, because C# doesn't accept that > the dllImport statement is located in a funktion like e.g. form_load.
>
> Does anyone have any idea to do this in a clever way?
>
> Thanks a lot!
> Ole
>
>



Nov 16 '05 #5
Ole,
I could make two versions of
the DllImported funktions but then I would have to ask for the OS version in
every call to the function.


Certainly not, one time is enough. all you have to do is wrap the
functionality in two system dependent classes that share a common
interface and let polymorphism do its magic.

Consider this

interface IMyApis {
bool ReadFile(...);
}

sealed class DesktopApis : IMyApis {
[DllImport("kernel32.dll", SetLastError=true)]
private static extern bool ReadFile(...);

bool IMyApis.ReadFile(...) { return ReadFile(...); }
}

sealed class PocketPCApis : IMyApis {
[DllImport("coredll.dll", SetLastError=true)]
private static extern bool ReadFile(...);

bool IMyApis.ReadFile(...) { return ReadFile(...); }
}
IMyApis api = Environment.OSVersion.Platform == PlatformID.WinCE ?
new PocketPCApis() : new DesktopApis();
api.ReadFile(...);

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Nov 16 '05 #6
Thanks Mattias

It looks like it's something worth trying out so I'll do - Thanks a lot!

Ole

"Mattias Sjögren" <ma********************@mvps.org> wrote in message
news:%2*****************@TK2MSFTNGP15.phx.gbl...
Ole,
I could make two versions of
the DllImported funktions but then I would have to ask for the OS version inevery call to the function.


Certainly not, one time is enough. all you have to do is wrap the
functionality in two system dependent classes that share a common
interface and let polymorphism do its magic.

Consider this

interface IMyApis {
bool ReadFile(...);
}

sealed class DesktopApis : IMyApis {
[DllImport("kernel32.dll", SetLastError=true)]
private static extern bool ReadFile(...);

bool IMyApis.ReadFile(...) { return ReadFile(...); }
}

sealed class PocketPCApis : IMyApis {
[DllImport("coredll.dll", SetLastError=true)]
private static extern bool ReadFile(...);

bool IMyApis.ReadFile(...) { return ReadFile(...); }
}
IMyApis api = Environment.OSVersion.Platform == PlatformID.WinCE ?
new PocketPCApis() : new DesktopApis();
api.ReadFile(...);

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Nov 16 '05 #7
ORC
Hi there,

NOP - it doesn't work. I get an error in this part:
IMyApis api = Environment.OSVersion.Platform == PlatformID.WinCE ?
new PocketPCApis() : new DesktopApis();

the error text is:
"Type of conditional expression can't be determined because there is no
implicit conversion between 'Ports.SerialPort.PocketPCApis' and
'Ports.SerialPort.DesktopApis'"

Code is made exactly as suggested and I don't get any other errors in the
code - the two dependend classes are exactly equal.

Any suggestion ???

Thanks
Ole

"Ole Christensen" <or*@sol.dk> wrote in message
news:uz**************@TK2MSFTNGP12.phx.gbl...
Thanks Mattias

It looks like it's something worth trying out so I'll do - Thanks a lot!

Ole

"Mattias Sjögren" <ma********************@mvps.org> wrote in message
news:%2*****************@TK2MSFTNGP15.phx.gbl...
Ole,
I could make two versions of
the DllImported funktions but then I would have to ask for the OS
version
inevery call to the function.


Certainly not, one time is enough. all you have to do is wrap the
functionality in two system dependent classes that share a common
interface and let polymorphism do its magic.

Consider this

interface IMyApis {
bool ReadFile(...);
}

sealed class DesktopApis : IMyApis {
[DllImport("kernel32.dll", SetLastError=true)]
private static extern bool ReadFile(...);

bool IMyApis.ReadFile(...) { return ReadFile(...); }
}

sealed class PocketPCApis : IMyApis {
[DllImport("coredll.dll", SetLastError=true)]
private static extern bool ReadFile(...);

bool IMyApis.ReadFile(...) { return ReadFile(...); }
}
IMyApis api = Environment.OSVersion.Platform == PlatformID.WinCE ?
new PocketPCApis() : new DesktopApis();
api.ReadFile(...);

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.


Nov 16 '05 #8
> NOP - it doesn't work. I get an error in this part:
IMyApis api = Environment.OSVersion.Platform == PlatformID.WinCE ?
new PocketPCApis() : new DesktopApis();

the error text is:
"Type of conditional expression can't be determined because there is no
implicit conversion between 'Ports.SerialPort.PocketPCApis' and
'Ports.SerialPort.DesktopApis'"

Code is made exactly as suggested and I don't get any other errors in the
code - the two dependend classes are exactly equal.

Any suggestion ???


IMyApis api;
if (Environment.OSVersion.Platform == PlatformID.WinCE) {
api = new PocketPCApis();
}
else {
api = new DesktopApis();
}

or

IMyApis api = Environment.OSVersion.Platform == PlatformID.WinCE ?
(IMyApis) new PocketPCApis() : (IMyApis) new DesktopApis();

bye
Rob

Nov 16 '05 #9
ORC
Great! thanks!

Regards
Ole

"Robert Jordan" <ro*****@gmx.net> wrote in message
news:cl*************@news.t-online.com...
NOP - it doesn't work. I get an error in this part:
IMyApis api = Environment.OSVersion.Platform == PlatformID.WinCE ?
new PocketPCApis() : new DesktopApis();

the error text is:
"Type of conditional expression can't be determined because there is no
implicit conversion between 'Ports.SerialPort.PocketPCApis' and
'Ports.SerialPort.DesktopApis'"

Code is made exactly as suggested and I don't get any other errors in the code - the two dependend classes are exactly equal.

Any suggestion ???


IMyApis api;
if (Environment.OSVersion.Platform == PlatformID.WinCE) {
api = new PocketPCApis();
}
else {
api = new DesktopApis();
}

or

IMyApis api = Environment.OSVersion.Platform == PlatformID.WinCE ?
(IMyApis) new PocketPCApis() : (IMyApis) new DesktopApis();

bye
Rob

Nov 16 '05 #10

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

Similar topics

15
by: Jim | last post by:
I am extremely frustrated. I am building c# application for a call center and am using a third party API to access some hardware. When develop and test my class using the windows console the...
6
by: Tim Mulholland | last post by:
Whats the correct C# datatype (or marshalling function or something) to use when you're importing a function that has a signature similar to char* FuncA(char c) ? Assuming you know that...
3
by: Mark Jerde | last post by:
I'm sill learning VS .NET 2003, not an expert yet. I'm calling an unmanaged C++ DLL from C# using . When the whole project is done I will be calling a total of 5 C++ DLLs from C#. All the DLLs...
1
by: Brian Anderson | last post by:
Hello, I have a native, C++ console app that uses ~26MB of RAM when it runs. It uses quite a lot of RAM to make some math but will never xceed 26MB. Now I've made a dll out of this code and...
2
by: Brian Anderson | last post by:
Hello, is it possible to use DllImport to call a DLL in ASP.NET ? Or is it necessarry that my DLL has to be copied into \System32 ? My DLL is a native C++ 7.1 DLL (not managed, no COM, no...
2
by: Ed | last post by:
Hello, dear all, I often see these two import usage in the code. Both are the interface to use the Dll library. I think they are the same. Normally P/Invoke means using the to import the dll....
1
by: kardon33 | last post by:
Let me explain my problem, Im currently trying to use a Perl module that was built for a Windows OS that uses a .dll and .lib file. I have obtained the c header files that the modules were built...
9
by: jjones7947 | last post by:
Am doing a JNI wrap on a C++ API, am using VC7 and Eclipse. In preparation, I created a C++ executable which mimicked the flow of the JNI, i.e. a driver file which called methods in file with methods...
1
by: elke | last post by:
Hi, I want to use an unmanaged dll in C# .net and I'm having some troubles witch a function that should return an array. I'm new at this, so I don't know what I'm doing wrong. Here is some...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
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,...
0
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...
0
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,...
0
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...

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.