Wednesday, October 09, 2013

How to use .NET C# COM objects in plain C

Preface
I've recently encountered such a problem: how to call a property or method from C project in C# class? Google gives me an inaccurate info of what to do with this kind of problem. I spent some time on it and when I finally know what to do I decided to share this knowledge with the others - maybe I could save someone some time.

I want to announce - I am not a C/C++ programmer rather I work with C# so if you know how something could do better just email me or post a suggestion in comments. What I want to present here is a straightforward solution for anyone who is not familiar with C/C++/COM programming.

Introduction
This article covers a basic setup for creation of communication between .NET objects (through COM) to plain C (without any help from CLR and/or additional frameworks). This can gives you a possibility to call .NET (created in C# or VB) methods, properties etc. directly from plain C project.

Our goal will be to acquire some data from C# Class Library back to Win32 Console Application. Sounds simple but it requires a few steps to accomplish. Let's get started!

1. Setup proper compiler options
1.1 First we need to create a solution within Visual Studio (I use VS2008 Pro). Let's choose: File -> New -> Project, then Other Languages -> Visual C++ -> Win32 Console Application. I named it "plainC". After clicking 'OK' the project wizard should pop up. After clicking 'Next' I recommend to uncheck Precompiled header option unless you are familiar with it. To finish click 'Finish'.

1.2 As you can see IDE produces *.cpp class and indeed it's a C++ project instead of C. Let's change this. We need to rename our main file from plainC.cpp to plainC.c.

1.3 Next we need to change compile language option: right click on project -> Properties then Configuration Properties -> C/C++ -> Advanced -> Compile As and choose: Compile as C Code (/TC).

The rest of options may (or should for this solution) remain as they are. Especially in general configuration properties tab:


Inline images 1

1.4 OK now we can create C# class (for convenience let's do this in current solution). Create new project in Visual C# -> Windows and choose: Class Library. I named project as "CSharpLib".

1.5 Into the project properties we may set an automatic registering our assembly for COM interoperability. We can find this option under: Build -> Register for COM interop. If for some reason you don't want to do this automatically then use regasm.exe (for further details and some info of how to use it you may look into msdn).

2. Preparing the .NET code
2.1 Now we can finally add new class to the C# project - for example: NetClass with some properties and with explicit default constructor. We need also an interface (INetClassComVisible) because through it we will call the class members later.

 Collapse | Copy Code
using System;
using System.Runtime.InteropServices;
 
namespace CSharpLib
{
    [ComVisible(true)]
    [Guid("1A741C67-8D57-4a83-8E0B-834D6D526D0C")]
    [ClassInterface(ClassInterfaceType.None)]
    public class NetClass : INetClassComVisible
    {
        public string StringValue
        {
            get
            {
                return "Example string";
            }
        }
 

Read more: Codeproject
QR: Inline images 2