Visual C++ 2010 - Unmanged C calling managed c++ dll

Hi, I'm a C / C++ noob, but have been a software engineer for 28 years. I just started a new job, and have inherited some unmanaged C code to maintain.

I need to modify this C code to call a C++ managed / CLR DLL that will take care of decrypting data.

I've searched the web, but nothing seems to fit the specific case I have.

I'd post code, but there's nothing to it. In pseudocode it's :

VS 2010 C program :

read file
while not(eof)
call managed DLL decrypt routine to decrypt certain values
read next record
end While

VS 2010 Managed C++ DLL

Get parm
Decrypt parm
Return value

I've tried various things like regasm and so on but got nowhere.

Any pointers would be really appreciated.

Have to have this sorted by Friday.

Thanks,
Jennifer
See the following web page for some assistance on calling a managed DLL from unmanaged code. How come you didn't find anything on the web?

http://support.microsoft.com/kb/828736
Did that help or not???
Sorry, was off line last few days due to illness - I'll check that link out and get back to you.

Thanks :)
Actually I found that link before and followed it's instructions, but it didn't work.

The link is about unmanaged c++ calling managed c++

what I need is unmanaged C calling managed c++
You should still be able to use COM from your C program.

I created a managed DLL as described in the article and then an unmanaged prgram thus:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Import the type library.
#import "..\..\\aManagedDLL\\bin\\Debug\\ManagedDLL.tlb" //raw_interfaces_only

using namespace ManagedDLL;

int main(int argc, char* argv[])
{
	// Initialize COM.
	HRESULT hr = CoInitialize(NULL);

	// Create the interface pointer.
	ICalculatorPtr pICalc(__uuidof(ManagedClass));

	//long lResult = 0;

	// Call the Add method.
	long lResult = pICalc->Add(5, 10);

	printf("The result is %d", lResult);

	// Uninitialize COM.
	CoUninitialize();
	return 0;
}


All works.

If you want you could send me a PM on this.
Thanks, I'll give that a try and get back to you in the afternoon my time (Ireland). Having a crazy day today so it will be approx 2 hrs before I get to try it out.

Kind regards,
Jennifer
Hi, tried that - it won't compile

error : C2061 -syntax error : identifier 'namespace'

This error is in the C program, which is compiled with the C compiler - it's not possible to convert it to C++, it would need a complete rewrite.

Had another go at trying this, leaving the namespace out.

error C2773: #import and #using available only in C++ compiler
How large is the ANSI C program? Can't you convert it to C++?
No way it will covert in the time I have available - it's part of a larger C based application, and it's not well written (in my opinion). Also, I'm a C++ noob, so there's no way I've got the skills yet to do a job like that in a short space of time. Trying to compile with the c++ compiler gives a couple of hundred errors.

I guess I need to re-think this - I wanted to keep the C application as is, apart from a call to my external c++ DLL, but it looks like I'll have to get into the C code and accomplish what I need there.

For the moment a trivial XOR encryption will suffice, and over the weekend I'll try to implement libtomcrypt with the application.

Is there an easy to use C based encryption library you would recommend, as an alternative to libtomcrypt?
I use OpenSSL

http://www.openssl.org

What does the main C application do?
It's part of a in-house ERP package, used for controlling the packing out of active ingredient for a pharmaceutical plant. Really needs to be replaced with something more modern and maintainable, and more in line with FDA guidelines for such systems.

The guy who usually worked on it got his ass fired on Monday, so I got lumped with it :(

Thanks a million for taking the time to help with this - I'll check out openssl over the weekend.

Many thanks,
Jennifer
Good luck with it. BTW - I'm in the UK. I don't have Windows at home, I have OSX and Linux at home, so won't be able to help out over the weekend apart from advice.
If you remember to declare your extern functions as "C", you could just add an extra C++ file to your project to do the .Net related work.

This code is based on a normal Win32 console app (i.e. unmanaged).

1
2
3
4
5
6
7
8
9
// main.c

#include "net_shim.h"

int main() {
    write_msg("Hello, .Net world");

    return 0;
}


1
2
3
4
5
6
7
8
9
10
11
12
13
#pragma once

// net_shim.h

#ifdef __cplusplus
extern "C" {
#endif

int write_msg(char* pszMsg);

#ifdef __cplusplus
} // extern "C"
#endif 


The properties of the .cpp file need to be altered so that the /clr compiler flag is used for this file. Note it means you have to adjust some of the other default flags (e.g. /ZI -> /Zi, for the debug build)

1
2
3
4
5
6
7
8
9
10
11
12
13
// net_shim.cpp (built with /clr compiler flag, so it
// supports managed code)

using namespace System;

#include "net_shim.h"

int write_msg(char* pszMsg)
{
	String^ msg = gcnew String(pszMsg);
	Console::WriteLine(msg);
	return 0;
}


Hello, .Net world

Whether this approach is better or not, than swapping to an alternative cryptographic library, depends on the data types you need to pass to the .Net functions (i.e. how much work there is to marshall the data)

Andy
Last edited on
Thanks Andy, I'll give that a try - I tried the extern C earlier this week, but perhaps I didn't do it correctly.

I'll try with your example and let you know how I get on.

Thanks,
Jennifer
Well, the extern C just gets you to C++. That's the easy part; it's the unmanaged/managed stuff that's more the problem.

The mixed-mode approach should be more efficient than the interop approach in the article ajh32 mentions. But it does depend on the API you're using.

Andy
Hi Andy,

OMG it worked!!

This is perfect - now I can encapsulate the code changes in a C++ program and use the System::Security::Cryptography library for my task. Minimum changes will then be required to the original C code, which is exactly what I needed.

Thank you both for your efforts and your time - you have really saved my bacon this week!! I hope I get the opportunity to repay the favour in the future!

Now I have to write a mountain of documentation for the validation team!#

With sincere thanks,
Jennifer

PS A C translation of the COM solution in

How to call a managed DLL from native Visual C++ code in Visual Studio.NET or in Visual Studio 2005
http://support.microsoft.com/kb/828736

is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// CClient.c

#define _WIN32_WINNT 0x0600

#include <stdio.h>
#include <tchar.h>

#include "smanageddll.h"
#include "smanageddll_i.c"

int _tmain(int argc, _TCHAR* argv[])
{
    HRESULT      hr      = S_OK;
    long         lResult = 0;
    ICalculator* pICalc  = NULL;

    // Initialize COM.
    hr = CoInitialize(NULL);

    if( FAILED(hr) )
    {
        fprintf(stderr, "CoInitialize failed: 0x%08x\n", hr);
    }
    else
    {
        // Create the interface pointer.
        hr = CoCreateInstance( &CLSID_ManagedClass,
                               NULL,
                               CLSCTX_INPROC_SERVER,
                               &IID_ICalculator,
                               &pICalc );

        if( FAILED(hr) )
        {
            fprintf(stderr, "CoCreateInstance failed: 0x%08x\n", hr);
        }
        else
        {
            // Call the Add method.
            pICalc->lpVtbl->Add(pICalc, 5, 10, &lResult);

            wprintf(L"The result is %d\n\n", lResult);
        }

        // Uninitialize COM.
        CoUninitialize();
    }

    return 0;
}


But I only did it to remind myself how to use COM from C (not something I'd do by choice!)

Andy

PS To get the .h and _i.c you've got to open the .tlb file generated by regasm.exe with OLE-COM Object Viewer and export (Save As) the .h, .c, and .idl (This didn't work for me: the idl file ws truncated. So I cut and paste the .idl from the viewer's windows and then ran midl on it:

midl /Oicf sManagedDLL.IDL  /h sManagedDLL.h

Then copied the files where I needed them.

PPS This knowledgebase article does seem to be long in the tooth. Even with VC++2008 I had to make tweaks (inc. the inconsistent name of the managed DLL -- sManagedDLL vs ManagedDLL).
Last edited on
Topic archived. No new replies allowed.