1

Here i created in DLL project in vc++ 2008. Following are two code files lib.h and lib.cpp.

lib.h

   #include "stdafx.h";


    class __declspec(dllexport) test
    {
    public:
        test();
        static void  hello();
        static void  hello1();
    };

    class __declspec(dllexport) test1
    {
    public:
        test1();
        void  hello_test1();
        void  hello1_test1();

    };

lib.cpp

    #include "stdafx.h"
    #include "lib.h"
    #include <stdio.h>

    void test::hello()
    {   
        printf("Hello");
    }

    void test::hello1()
    {
        printf("Hello1");
    }

    void test1::hello_test1()
    {
        printf("Hello_test1");
    }

    void test1::hello1_test1()
    {
        printf("Hello1_test1");
    }

stdafx.h

#include "targetver.h"
#define WIN32_LEAN_AND_MEAN 
// Windows Header Files:
#include <windows.h>

dllMain.cpp

#include "stdafx.h"

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

I have written C# code to call the method of test and test1 classes:
ConsoleApp

    [DllImport("lib.dll" )]
    public static extern void hello();

    [DllImport("lib.dll")]
    public static extern void hello1();

    [DllImport("lib.dll")]
    public static extern void hello_test1();

    [DllImport("lib.dll")]
    public static extern void hello1_test1();

 static void Main()
{ 
        hello();
        hello1();
        hello_test1();
        hello1_test1();
        Console.ReadKey();
    }

when i run above code i have got following error: EntryPointNotFoundException: Unable to find an entry point named 'hello' in DLL 'lib.dll' enter image description here
I know about how to call function only(without using Class) of vc++ DLL from C# but i don't know how to call method of any class and how to code that in proper way in vc++.

I know somewhere is mistake in my above code, please experts guide me about my mistake because i tried all from my side.

If anyone has full example like above then suggest me.

Thanks in advance..

Himanshu
  • 4,327
  • 16
  • 31
  • 39
  • i am not sure if this will works as i never have imported from c++ code. try tu add your .dll as reference and then use "using lib.dll" – U. Busto Mar 16 '15 at 11:00
  • lib.dll is contain unmanaged code because it is developed in vc++ so it can't added as refrence. – Bhavesh Ahir Mar 16 '15 at 11:05
  • You have declared classes in your DLL but try to invoke methods of these classes like normal functions. This won't even work in normal code without a DLL. Maybe this helps: http://stackoverflow.com/questions/4555961/how-to-use-a-class-in-dll – user0815 Mar 16 '15 at 11:06
  • this is very simple example. when i define hello() function instead of test::hello() in lib.cpp there is no error and got proper output but error only occurs when i define this method in class and call it through that class. – Bhavesh Ahir Mar 16 '15 at 11:19
  • It isn't called "hello" after the C++ compiler is done with it. You need to use the Entrypoint property in your [DllImport] declaration. Use the .map file or use Dumpbin.exe /exports to see the real name. You'll see that test::hello() turned into "?hello@test@@SAXXZ". – Hans Passant Mar 16 '15 at 11:59

2 Answers2

0

As far as I'm aware there is no way to directly call a native class method from c#. The typical way to get around this is to make non-member functions that call the class methods and interact with those. Please refer to the following link for more specifics. It includes a direct example of what you are trying to do.

using a class defined in a c++ dll in c# code

After reading more of the answers it might be possible but it appears that the link shows the examples you are looking for.

Community
  • 1
  • 1
-2

@Jarrett Thanks for moving me towards to Marshal concept.

I added testClass.h and testClass.cpp in this project to marshal C++ classes

testClass.h

#ifndef __testClass_h__
#define __testClass_h__

#include "lib.h"

#ifdef __cplusplus
extern "C" {
#endif

extern LIBDLL_API test* createTestClass();
extern LIBDLL_API void disposeTestClass(test* pObject);

extern LIBDLL_API void callHello(test* pObject);
extern LIBDLL_API void callHelloTest1Class(test1* pObject);

#ifdef _cplusplus

#endif
}
#endif

testClass.cpp

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "stdafx.h"
#include "testClass.h"

extern "C" LIBDLL_API test* createTestClass()
{
    return new test();
}

extern "C" LIBDLL_API void disposeTestClass(test* pObject)
{
    if(pObject!=NULL)
    {
        delete pObject;
        pObject=NULL;
    }
}

extern "C" LIBDLL_API void callHello(test* pObject)
{
    if(pObject!=NULL)
    {
        pObject->hello();
    }
}

extern "C" LIBDLL_API void callHelloTest1Class(test1* pObject)
{
    if(pObject!=NULL)
    {
        pObject->hello_test1();
    }
}

lib.h

#include "stdafx.h";
#ifdef LIB_EXPORTS
    #define LIBDLL_API __declspec(dllexport)
#else
    #define LIBDLL_API __declspec(dllimport)
#endif

class LIBDLL_API test
{
public:
    test();
    virtual ~test();
    static void  hello();
    static void  hello1();

};

class LIBDLL_API test1
{
public:
    test1();
     void  hello_test1();
     void  hello1_test1();

};

lib.cpp

#pragma once
#include "stdafx.h"
#include "lib.h"
#include <stdio.h>
#include <iostream>

#define WIN32_LEAN_AND_MEAN     // Exclude rarely-used stuff from Windows headers
#include <windows.h>


test::test()
{}
test::~test()
{}

void test::hello()
{   
    printf("\nHello");
}


void test::hello1()
{
    printf("Hello1");
}

void test1::hello_test1()
{
    printf("\nHello_test1");
}
void test1::hello1_test1()
{
    printf("Hello1_test1");
}

And now create a console application and add some code in program.cs file
Program.cs

namespace ConsoleApplication1
{
    class ConsoleApplication1
    {

        static void Main()
        {
            CS_Test_Class testClass = new CS_Test_Class();
            testClass.hello();
            testClass.hello_test1();

            Console.ReadKey();
            testClass.Dispose();

        }

    }
}

program.cs call the method of CS_Test_Class.cs So....
CS_Test_Class.cs

using System;
using System.Runtime.InteropServices; 
namespace ConsoleApplication1
{
    public class CS_Test_Class:IDisposable
    {
        [DllImport("lib.dll")]
        public static extern IntPtr createTestClass();

        [DllImport("lib.dll")]
        static private extern void disposeTestClass(IntPtr pTestClassObject);

        [DllImport("lib.dll")]
        static private extern void callHello(IntPtr pTestClassObject);

        [DllImport("lib.dll")]
        static private extern void callHelloTest1Class(IntPtr pTestClassObject);


        private IntPtr nativeObject;

        public CS_Test_Class()
        {
            this.nativeObject = createTestClass();
        }

        public void Dispose()
        {
            Dispose(true);
        }
        protected virtual void Dispose(bool bDisposing)
        {
            disposeTestClass(this.nativeObject);
            this.nativeObject = IntPtr.Zero;

            if (bDisposing)
                GC.SuppressFinalize(this);
        }

        ~CS_Test_Class()
        {
            Dispose(false);
        }

        public void hello()
        {
            callHello(this.nativeObject);
        }
        public void hello_test1()
        {
            callHelloTest1Class(this.nativeObject);
        }

    }
}

Marshling allows you to acces the class and method of c++ Dll. Microsoft provides facility to Marshal C-functions and also provides the mechanism to Marshal c++ clases.

Enjoy Marshling... Thank you.