473,324 Members | 2,581 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,324 software developers and data experts.

Calling unmanaged C++ DLLs

I am having trouble using Platform Invoke to call C++ DLLs
from C# windows applications. The DLLs seem to load, but I
get run-time errors to the effect that the named entry
points cannot be found. The DLLs are compiled in MS Visual
C++ Version 6 and the C# applications are written in MS VS
C#.NET 2003. I am using the specifier _declspec(dllexport)
for a class in the DLL and I am using DllImport(...) for
each method imported into the C# program.
What am I doing wrong ?
Any suggestions would be welcome.

Andrew Cumming.
Nov 13 '05 #1
9 18015
Andrew Cumming wrote:
I am having trouble using Platform Invoke to call C++ DLLs
from C# windows applications. The DLLs seem to load, but I
get run-time errors to the effect that the named entry
points cannot be found. The DLLs are compiled in MS Visual
C++ Version 6 and the C# applications are written in MS VS
C#.NET 2003. I am using the specifier _declspec(dllexport)
for a class in the DLL and I am using DllImport(...) for
each method imported into the C# program.
What am I doing wrong ?
Any suggestions would be welcome.

Andrew Cumming.


If I were you I would use dumpbin on the dll. I suspect that you are
experiencing the effects of namemangling.

Tom Shelton

Nov 13 '05 #2
"Andrew Cumming" <am********@bigpond.com> wrote in message news:<06****************************@phx.gbl>...
I am having trouble using Platform Invoke to call C++ DLLs
from C# windows applications. The DLLs seem to load, but I
get run-time errors to the effect that the named entry
points cannot be found.

....
In general, it's easiest to implement a set of unmangled C wrappers
that serve as glue between C# and C++. My experience shows that there
are 3 essential components, usually separate projects (of course the
C# and C++ side are separate)

A) The baseline C++ Stuff

B) The 'plugin' wrapper, which provides a set of C functions that map
to the relevant C++ bits.

C) A set of classes in C# that map to the plugin.

I'll ignore A, I assume you've got the C++ code.

Here's an example of Plugin C wrappers for C++
// definitions
extern "C" {
CSEXPORT(void) SystemMessage(char* theMessage);
CSEXPORT(void) StartCore(ULONG windowHandle,int serviceID);
CSEXPORT(void) StartQuestor(char* appname);
CSEXPORT(void) OpenQuestor(char* appname);
CSEXPORT(void) ActivateSubsystems();
CSEXPORT(void) StopV3();
// PERSISTANT FILES
CSEXPORT(ULONG) CreateUMF(char* theName);
CSEXPORT(ULONG) OpenUMF(char* theName);
CSEXPORT(ULONG) ReadUMF(ULONG umfptr);
CSEXPORT(void) WriteUMF(ULONG umfptr,ULONG objptr);
CSEXPORT(void) CloseUMF(ULONG umfptr);
CSEXPORT(ULONG) LoadExternalModel(const char* theFile,short
mirrorAxes,short mirrorTexture,short reversals);
};

// and here's an example function
// PERSISTANT FILES
CSEXPORT(ULONG) CreateUMF(char* theName)
{
CUMF* aUMFFile = new CUMF();
try {
aUMFFile->Create(theName);
} catch(...) {
SAFE_DELETE(aUMFFile);
return 0;
}
return (ULONG) aUMFFile;
}

Note that we return direct object pointers to C#, which treats them as
handles, effectively. There are good and bad points to this approach
:-)

CSEXPORT(ULONG) is defined as
#define CSEXPORT(type) __declspec(dllexport) type __cdecl
Supposedly you can use fastcall, but it's a real PITA

C - The C# side of the house

public class V3UMF
{
#region V3 Interface DLL Imports
[DllImport("CS2V3.dll")]
private static extern IntPtr CreateUMF(string theName);
[DllImport("CS2V3.dll")]
private static extern IntPtr OpenUMF(string theName);
[DllImport("CS2V3.dll")]
private static extern IntPtr ReadUMF(IntPtr umfptr);
[DllImport("CS2V3.dll")]
private static extern void WriteUMF(IntPtr umfptr,IntPtr objptr);
[DllImport("CS2V3.dll")]
private static extern void CloseUMF(IntPtr umfptr);
[DllImport("CS2V3.dll")]
private static extern IntPtr LoadExternalModel(string theFile,short
mirrorAxes,short mirrorTexture,short reversals);
#endregion
private IntPtr m_umf;

public V3UMF()
{
m_umf = (IntPtr) 0;
}
public void Open(string filename)
{
m_umf = OpenUMF(filename);
}
public void Create(string filename)
{
m_umf = CreateUMF(filename);
}
public void Close()
{
CloseUMF(m_umf);
m_umf = (IntPtr) 0;
}

~V3UMF()
{
if(m_umf != (IntPtr) 0)
CloseUMF(m_umf);
}
public bool Opened
{
get { return m_umf != (IntPtr) 0;}
}
public V3Object ReadObject()
{
IntPtr ip = ReadUMF(m_umf);
if(ip == (IntPtr) 0)
return null;
else
return new V3Object(ip).DownCast();
}
public void WriteObject(V3Object anything)
{
WriteUMF(m_umf,anything.Handle);
}
static public V3Shape LoadExternalModel(string theName,bool
mirrorAxes,bool mirrorTexture,bool revFaces,bool revNormals,bool
revMatrix)
{
short mt = (short) (mirrorTexture ? 1 : 0);
short ma = (short) (mirrorAxes ? 1 : 0);
short revs = 0;
if(revFaces)
revs += 1;
if(revNormals)
revs += 2;
if(revMatrix)
revs += 4;
IntPtr theShapePtr = LoadExternalModel(theName,ma,mt,revs);
if(theShapePtr == (IntPtr) 0)
return null;
else
return new V3Shape(theShapePtr);
}
}
One last detail of note, architecture wise. You end up with object
representations on both sides of the fence, i.e. in C++ and in C#.
The thing that separates the crazed from the dead is the method by
method decision process as to whether
A) You'll reimplement the functionality on the C# side because it's
faster to do it than call it
B) Or vice versa
Nov 13 '05 #3
> In general, it's easiest to implement a set of unmangled C wrappers
that serve as glue between C# and C++. My experience shows that there
are 3 essential components, usually separate projects (of course the
C# and C++ side are separate)


I think a case could be made for managed C++ wrapping rather than C
wrapping.

Cheers,

4Space
Nov 13 '05 #4
True iff you want to incorporate automatic garbage collection. Not
always the best idea when the stuff in C++ is there for significant
performance reasons. I've avoided this thus far, because of 1
question and 1 issue

question - what overhead does gc introduce into the C++ side? I care
a lot about this, the example was from a 3d engine.

issue/question - It doesn't seem I can have my cake and eat it too,
i.e. __gc is a global class operator, I can't say sometimes I want
this class managed and sometimes I don't.

Probably not bad in general, but using C wrappers makes everything
nice and clean and keeps msfts mitts out of things when performance is
an issue. All the examples I've seen thus far for managed C++ are
actually better arguments for why you shouldn't be using C++ in the
first place, or are simply contrived.

All that aside, yes a case can be made. I just have trouble buying
it.

l8ter

"4Space" <4S****@NoSpam.com> wrote in message news:<TY********************@news.easynews.com>...
In general, it's easiest to implement a set of unmangled C wrappers
that serve as glue between C# and C++. My experience shows that there
are 3 essential components, usually separate projects (of course the
C# and C++ side are separate)


I think a case could be made for managed C++ wrapping rather than C
wrapping.

Cheers,

4Space

Nov 13 '05 #5
> question - what overhead does gc introduce into the C++ side? I care
a lot about this, the example was from a 3d engine.
Well, if you're wrapping the unmanaged C++ class, and managing to not copy
data back and forth from the managed code, then negligible, if existent.

Like you, we have some computationally intensive numerical algorithms for
which execution speed is a serious consideration. We've simpy created a __gc
class that aggregates a __nogc C++ class, and exposes a similar interface.
This way, the functionality is available to managed clients, but the
computation is done by unmanaged code.
issue/question - It doesn't seem I can have my cake and eat it too,
i.e. __gc is a global class operator, I can't say sometimes I want
this class managed and sometimes I don't.
I'm not sure I understand what it is you're trying to do. The unmanaged
class will still exist. Managed clients would talk to the managed wrapper,
unmanaged clients would talk directly to the unmanaged class.
Probably not bad in general, but using C wrappers makes everything
nice and clean and keeps msfts mitts out of things when performance is
an issue. All the examples I've seen thus far for managed C++ are
actually better arguments for why you shouldn't be using C++ in the
first place, or are simply contrived.


Perhaps something to consider, is that the Managed C++ compiler is (or at
least was - not tested VC7.1) better at producing optimised MSIL code. But
yes, managed C++ is an awful language, but often a necessary evil.

Post back if you have any further queries on the subject. Can't guarantee an
answer, but I'll happily share what I know.

Cheers,

4Space
Nov 13 '05 #6
>
Like you, we have some computationally intensive numerical algorithms for
which execution speed is a serious consideration. We've simpy created a __gc
class that aggregates a __nogc C++ class, and exposes a similar interface.
This way, the functionality is available to managed clients, but the
computation is done by unmanaged code.
Hmmm. __gc aggregating a _nogc. Seemes like roughly the same amount
of work as a C wrapper. Granted its probably prettier. Mebbe I'll
look into that.
issue/question - It doesn't seem I can have my cake and eat it too,
i.e. __gc is a global class operator, I can't say sometimes I want
this class managed and sometimes I don't.
I'm not sure I understand what it is you're trying to do. The unmanaged
class will still exist. Managed clients would talk to the managed wrapper,
unmanaged clients would talk directly to the unmanaged class.


Didn't know of your approach. I guess if I had __nogc CShape being
aggregated by __gc CShapeGC class, I could have external clients
instantiate the _gc and internal libraries use the CShape class that
would work. On the other hand, calls between C# and C++ aren't
exactly high performance beasts. Usually end up with the shared
classes mirrored on both sides, so that C# can _do_ instead of _call_
when that would be quicker. Which then leads to the question - if
there's a heavyweight C# class and a heavyweight C++ class, isn't the
_gc class in the middle pretty transient, i.e. it really only exists
to map the two classes together ? Seems C function wrappers are still
a cleaner solution with all things considered, albeit uglier.

An extreme in our world is 2,3, and 4 d points, 4space :-). Those are
basically duplicated on both sides, C# can compute a dot product a lot
faster than go through all the trouble to get the C++ library to do
it.
The other extreme would be a CScene class instance. Certainly some
applicability there, other than minor nits noted above. In the middle
are things like geometry and polygon classes, where some functions get
reimplemented in C# and some are just calls into C++. I'd be curious
if you had similar situations, and how you mapped _gc and _nogc to
issues of efficiency.

Perhaps something to consider, is that the Managed C++ compiler is (or at
least was - not tested VC7.1) better at producing optimised MSIL code. But
yes, managed C++ is an awful language, but often a necessary evil.
Yeah, but thats my point. If I want MSIL code I use C#, unless you're
telling me C# can't optimize as well as C++. I use C++ because I
really really care, and I don't want Pascal.

Post back if you have any further queries on the subject. Can't guarantee an
answer, but I'll happily share what I know.

Cheers,

4Space

Nov 13 '05 #7
> Yeah, but thats my point. If I want MSIL code I use C#, unless you're
telling me C# can't optimize as well as C++. I use C++ because I
really really care, and I don't want Pascal.


I spoke to Stann Lippman about it just over a year ago at a conference here
in the UK. I think at the time, he was working on the managed C++ compiler
team, and his viewpoint was that although in theory, the same application
coded in C# or managed C++ should yield the same MSIL, the truth of it was
that the managed C++ compiler produced MSIL with better optimisation.

But like I said, I haven't benchmarked it using the VS2003. Come to think of
it, I'm not sure that it isn't still illegal to publish benchmark results on
..NET ;¬)

Cheers,

4Space
Nov 13 '05 #8
Well, Stan's likely to say that, he's many years in the C++ saddle. I
don't know if I'd agree or wonder on principle, on the one hand the
C++ code may provide additional hintage, on the other hand managed C++
probably isn't too different from C# in the parse tree, ignoring a few
of the newer instructions.

Perhaps I'll profile some of this at some point, it's a public product
now.

Thx for the info!

MMM

"4Space" <4S****@NoSpam.com> wrote in message news:<NO********************@news.easynews.com>...
Yeah, but thats my point. If I want MSIL code I use C#, unless you're
telling me C# can't optimize as well as C++. I use C++ because I
really really care, and I don't want Pascal.


I spoke to Stann Lippman about it just over a year ago at a conference here
in the UK. I think at the time, he was working on the managed C++ compiler
team, and his viewpoint was that although in theory, the same application
coded in C# or managed C++ should yield the same MSIL, the truth of it was
that the managed C++ compiler produced MSIL with better optimisation.

But like I said, I haven't benchmarked it using the VS2003. Come to think of
it, I'm not sure that it isn't still illegal to publish benchmark results on
.NET ;¬)

Cheers,

4Space

Nov 13 '05 #9

Many thanks to those who responded.

It seems that you cannot export into C# classes of static
C++ methods in the way the C# documentation suggests
(Consuming Unmanaged DLLs). But, as the respondents
suggest, you can wrap the methods as global C functions
and export these using syntax such as :

extern "C"
{
_declspec(dllexport) int _cdecl func();
// ...
}
Nov 13 '05 #10

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

Similar topics

4
by: jarmopy | last post by:
Hi, I have made a service with C# and calling that service class from another C# program with remoting. (Referendes from the calling program) That service class is configured so that garpage...
7
by: Chris | last post by:
Background: We have developed an C# MDI (Multi-Document Interface) application which loads different assemblies/forms, so that the user can have many "application windows" running within the...
0
by: Frank Lopez | last post by:
My program structure is: 1. 2. 3. => manually does the crt-init and crt-terminate calls 4. -- this is accessed by the unmanaged C++ classes in (3) using LoadLibrary and FreeLibrary
0
by: monika.saxena | last post by:
Hi all, In one of my projects which is a web based application in asp.net, a third party tool - "Frontline Solver DLL" (It is an unmanaged DLL and ..NET is calling it using the PInvoke) is used....
1
by: Mike Walsh | last post by:
Hi All, I have an unmanaged C++ DLL built in Visual Studio 4.2. This DLL exports a class, which I want to use in my VC++ .NET 2003 app. Everything works fine however some of the methods in the...
4
by: harifajri | last post by:
Hi All, We know that if we want to list down all methods/functions on an unmanaged DLL, we can use command-line tools 'dumpbin' or 'link ' For example, if we want to know method from...
3
by: Klaus | last post by:
Hi, I have an existing VC 6 MFC application which communicates asynchronly with a VC 2005 managed code dll. I use an unmanaged base class with virtual functions to access methods in the MFC...
0
by: =?Utf-8?B?UGFy?= | last post by:
Hi I have a question on how to import unmanaged DLLs into Visual Studio 2005, C# environment. The background is that an instrument we bought is controlled through a couple of DLL files. I...
1
by: genesistr | last post by:
I have two 3rd party unmanaged c++ dll and one C++ project which uses these dlls. In my asp.net project i added c++ project as reference but in runtime it fails with that error: Exception from...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...

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.