What's the best way to make a managed .dll that uses unmanaged classes and code?

0

0to60

I'm trying to create a .dll with VS.NET 2003 Architect that contains a math
computational component. I need the guts of the thing to be in native code,
as performance is key for that part. But, I need a .net wrapper because
this "calculator" is actually a component used by an enterprise app written
entirely in .net.

What I want to do is have one project. I've created an MC++ .dll project.
Its got a __gc class (the wrapper) and a handful of __nogc classes. I'm
having a number of problems with this. First off, as soon as I put a set a
pointer to the __nogc class from within my managed wrapper class'
constructor, the linker complains of unresolved external symbols for __cdecl
operator new and delete.

Here is the source code so far, its as basic as you can get:

// Calculator.h

#pragma once

using namespace System;

class InnerClass;

namespace Calculator
{
public __gc class Class1
{
public:
Class1();

private:
InnerClass* inner;
};
}

__nogc class InnerClass
{
public:
InnerClass();
~InnerClass();
};

// Calculator.cpp

#include "stdafx.h"

#include "Calculator.h"

Calculator::Class1::Class1()
{
inner = new InnerClass();
}

InnerClass::InnerClass()
{}

InnerClass::~InnerClass()
{}

Again, this project was created with File->New->Project, choosing VC++ class
library (.net). As for project properties, I haven't changed them from what
VS gave me.
 
W

William DePalo [MVP VC++]

0to60 said:
I'm trying to create a .dll with VS.NET 2003 Architect that contains a math
computational component. I need the guts of the thing to be in native code,
as performance is key for that part. But, I need a .net wrapper because
this "calculator" is actually a component used by an enterprise app written
entirely in .net.

What I want to do is have one project. I've created an MC++ .dll project.
Its got a __gc class (the wrapper) and a handful of __nogc classes. I'm
having a number of problems with this. First off, as soon as I put a set a
pointer to the __nogc class from within my managed wrapper class'
constructor, the linker complains of unresolved external symbols for __cdecl
operator new and delete.

Glibly, I'd suggest that an easier solution would be had by putting the
native code in "free" functions called by the member functions of your
managed classes than by trying to mix managed and non-managed object models.
In that way you can take advantage of the "it just works" (IJW) facility to
have managed and unmanaged functions reside in the same module as long as
you define the boundaries between the two environments with

#pragma managed

and

#pragma unmanaged

Of course, if your project is complex, the more elegant solution may require
proceeding in the way that you outlined. I suggest that you start reading
here for more information on mixed-mode applications:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmex/html/
vcconconvertingmanagedextensionsforcprojectsfrompureintermediatelanguagetomi
xedmode.asp

I used that link to get a mixed-mode project of mine off the ground. I had
the same problem that you did. I defined new and delete operators for my
classes. And because it wasn't necessary for me to squeeze every last ounce
of performance out, I used LocalAlloc() and LocalFree() to implement them.

Regards,
Will
 
0

0to60

William DePalo said:
Glibly, I'd suggest that an easier solution would be had by putting the
native code in "free" functions called by the member functions of your
managed classes than by trying to mix managed and non-managed object models.
In that way you can take advantage of the "it just works" (IJW) facility to
have managed and unmanaged functions reside in the same module as long as
you define the boundaries between the two environments with

#pragma managed

and

#pragma unmanaged

Of course, if your project is complex, the more elegant solution may require
proceeding in the way that you outlined. I suggest that you start reading
here for more information on mixed-mode applications:

Well as it turns out, there are HUGE performance implications when using
#pragma unmanaged to make certain methods unmanaged. I did a test of this
calculator thing that I need, and I'm finding that coding a regular ol'
Win32 .dll with free functions, and then calling those functions from my
__nogc class and using System.Interopservices.DLLImport is on the order of
5x faster than putting the equivalent code right in my project and compiling
it with #pragma unmanaged.
 
W

Wiliam DePalo [MVP VC++]

0to60 said:
Well as it turns out, there are HUGE performance implications when using
#pragma unmanaged to make certain methods unmanaged. I did a test of this
calculator thing that I need, and I'm finding that coding a regular ol'
Win32 .dll with free functions, and then calling those functions from my
__nogc class and using System.Interopservices.DLLImport is on the order of
5x faster than putting the equivalent code right in my project and compiling
it with #pragma unmanaged.

OK,not knowing your application, I'm willing to take your numbers on faith.

Of course, you want to minimize the transitions. What I was suggesting was
syntactic sugar - thin .Net wrappers around the functions that do the real
work without a lot of back and forth. Otherwise, the marshalling and
unmarshalling of arguments gets expensive.

Regards,
Will
 
D

demofo

The default MC++ class library wizard are generated managed code only, it
doesn't link to CRT/MFC/ATL, to support unmanaged code ,read the following
about how to build a mixed mode dll
http://support.microsoft.com/?id=814472
and to resolve the link error of operator new and delete, add back _DLL
preprocessor definitions

Ben
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top