Use existing C code in C# application

  • Thread starter Thread starter webdudeIA
  • Start date Start date
W

webdudeIA

I have a bit of existing C code that I would like to use in a C#
application. Can anyone direct me to some instructions on how to make
use of this?

I'd also like to find some step-by-step instructions to make a DLL
from this C program using Visual Studio .NET. I haven't been able to
find any .NET specific instructions.

Thanks.
 
Greets,

There are a few ways that you can re-use this code in Visual C#. One
way is to create a .NET Class Library using Managed C++ and wrap calls to
your unmanaged C code in managed classes which can be referenced from a C#
application.

If you want to create a DLL from your existing code which can be used by
managed and unmanaged classes alike, you can use Visual C++ to create a
"Win32 Project" and select DLL as the type of project. I'm a bit
old-fashioned when it comes to creating DLLs with Visual C++, so I typically
create a header file and wrap the exported function declarations as so:

#ifndef MYHEADER_H
#define MYHEADER_H

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

// Prototypes go here
void __stdcall Function(void);

#ifdef __cplusplus
}
#endif //__cplusplus

#endif // MYHEADER_H

If you use the above, the MYHEADER_H #ifndef is used to ensure the
header is included one. "#pragma once" does the same, however, the above
solution is portable to other platforms / tools. In your function
declarations and definitions, I typically specify the __stdcall calling
convention (arguments are pushed from right to left and the called function
pops the stack before return). Many Windows API functions use this
convention as it used less memory (the pop call was in one place instead of
after each call) and still works fine.

The #ifdef for __cplusplus checks to see if the C++ compiler is being
used to compile and if so, it wraps the declarations in an extern "C" block
in order to declare 'C' style linkage. I typically also provide a .DEF file
to declare the exports for the DLL which may look like the following:

LIBRARY MYDLL.DLL
EXPORTS
Function @1

While you don't need to explicitly assign an ordinal to the exported
function, it's a good idea to make sure that adding new functions at random
locations in the .DEF file later re-assign ordinals. (Keeps from breaking
older clients linked to a specific ordinal, but probably not nearly as much
an issue today as it was for me in the past.)

After you've created your DLL, you can either use Platform Invoke with
DllImport in your C# applications in order to call your exported function
or, add yet another dependency and just provide a thin Managed C++ wrapper
which links to the import library for your DLL. The downside to this is
that you have a class library DLL which you reference from your application
and you need to ship that with the DLL you created from your existing code.
However, and I haven't verfied this though it should seem possible, you can
probably have both your managed wrapper class and your exported functions in
one single C++ DLL.

Now, not sure if it is possible (someone please chime in if they've
tried it), but the ideal solution would be to create this single C++ DLL
that contains three things: a) the exported API functions using your
existing code that can be used by C/C++ clients; b) the managed C++ wrapper
class that can be used by the .NET languages which calls your API functions
internally; and c) the necessary exported functions and implementation used
by COM objects (along with the appropriate interfaces) to wrap your API in a
COM interface that can be used by client software that uses automation.

Regards,

Joe

webdudeIA said:
I have a bit of existing C code that I would like to use in a C#
application. Can anyone direct me to some instructions on how to make
use of this?

I'd also like to find some step-by-step instructions to make a DLL
from this C program using Visual Studio .NET. I haven't been able to
find any .NET specific instructions.

Thanks.
 
It seems like the easier route would be to encapsulate this in C++
managed call and then use that in my C# app.

"There are a few ways that you can re-use this code in Visual C#. One

way is to create a .NET Class Library using Managed C++ and wrap calls
to your unmanaged C code in managed classes which can be referenced
from a C# application. "

I got as far as creating the C++ project and adding a reference to
this from my C# app.

The IDE generated the main DLL file for me like this:
// This is the main DLL file.

#include "stdafx.h"

#include "CRC_Lib.h"

I tried to add my code (.c) lines below the #include "CRC_Lib.h" and
compile the CRC_Lib.cpp. This does compile but, I get linker errors.
Unresolved externals like this:

unresolved external symbol "unsigned int __cdecl fread....


As I said before I can reference this C++ project. (I'm getting
closer)

Any other ideas???
 
Greets,

It looks like you need to add the CRT library reference to your project.
These are not added for you by default when you create a managed C++
application. Go to your "Project Settings" dialog and under (VS.NET 2003)
"Configuration Properties", select the "Linker" folder and look at the line
which read "Additional Dependencies". For the debug version of your
application, link to msvcrtd.lib and for the release version, link to
msvcrt.lib.

Regards,

Joe

webdudeIA said:
It seems like the easier route would be to encapsulate this in C++
managed call and then use that in my C# app.

"There are a few ways that you can re-use this code in Visual C#. One

way is to create a .NET Class Library using Managed C++ and wrap calls
to your unmanaged C code in managed classes which can be referenced
from a C# application. "

I got as far as creating the C++ project and adding a reference to
this from my C# app.

The IDE generated the main DLL file for me like this:
// This is the main DLL file.

#include "stdafx.h"

#include "CRC_Lib.h"

I tried to add my code (.c) lines below the #include "CRC_Lib.h" and
compile the CRC_Lib.cpp. This does compile but, I get linker errors.
Unresolved externals like this:

unresolved external symbol "unsigned int __cdecl fread....


As I said before I can reference this C++ project. (I'm getting
closer)

Any other ideas???
 
Thanks for the previous tip. That got me much closer.

Still, I have one more linker error.

CRC_Lib error LNK2001: unresolved external symbol "int __cdecl
stat(char const *,struct stat *)" (?stat@@$$J0YAHPBDPAU0@@Z)

I can get this code to work as a Win32 console app. But, I'm not sure
which libraries are missing when I try to make this a managed class
for use in my C# app.
 
Back
Top