Error when use C++ Library in C#

Posted on 2008-11-10
Medium Priority
Last Modified: 2013-12-14

when I use my C++ DLL from C# like desriped here http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_23865024.html?cid=239#a22897897 it works at all.
But when I use the Connect function of the Library I get an AccessViolationException error:

Maybe the problem is because of the class...
Other functions of the lib eg. DDF2intIP works fine but this isn't declared in "class RSCT_TERMINALCONNECT_API Rsct_TerminalConnect".

Is there need for to create a new instance of the Library before I can access these functions?
How to do ...?


// Library Class
class RSCT_TERMINALCONNECT_API Rsct_TerminalConnect 
        // Konstruktion / Destruktion
        virtual                                         ~Rsct_TerminalConnect(void);
        // Verbindungshandling
                        int                                     Connect(int _port);
                        int                                     UpdateConnect(int _port, const char* _model);
                        int                                     Disconnect(int _port);
                        BOOL                            CheckDownloadmode(Reader* _pReader);
                        void                            Init();
                        void                            Terminate();
                        Rsct_TerminalManager* m_pTerminalManager;       
extern RSCT_TERMINALCONNECT_API int nRsct_TerminalConnect;
// CPP access it like
        Rsct_TerminalConnect* pTC = new Rsct_TerminalConnect();
        ret = pTC->Connect(GetPort());
    delegate int Connect(int _port); //<< this signature must match C++ function's signature.
    Connect connect;
    delegate int Disconnect(int _port); //<< this signature must match C++ function's signature.
    Disconnect disconnect;
    delegate int DDF2intIP(string _ip);
    DDF2intIP ddf2ip;

Open in new window

Question by:andre72
  • 2
  • 2

Expert Comment

ID: 22927340
I expected that something would go wrong when you try to access member functions of classes. I would guess that static functions should be fine.

The reason is that 'this' pointer is passed to the method implicitly by the compiler. (It is passed in ECX register). CLR environment (or may be it is C# only issue) does not allow you to specify the calling convention in code. There is some information available at http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.callconvthiscall.aspx but apparently it should be used only by compiler writers.

I have read about attempts to modify the assembly that C# compiler generates. It consist of three steps:
(1) Disassemble the managed DLL using ildasm.exe
(2) manually change the calling convention. Here's an example of how the MSIL code should look like after modification: http://blogs.msdn.com/borisj/archive/2006/07/29/683061.aspx
(3) Re-assemble MSIL code using ilasm.exe

There is another way if you wish to write a little bit of simple C++.
If you have access to C++ code, (it looks like you do), create a static counterpart for each public member function.
class RSCT_TERMINALCONNECT_API Rsct_TerminalConnect 
    virtual ~Rsct_TerminalConnect(void);
    int Connect(int _port);
    int UpdateConnect(int _port, const char* _model);
    int Disconnect(int _port);
    static Rsct_TerminalConnect* createNewRsct_TerminalConnect()
    { return new Rsct_TerminalConnect(); }
    static void deleteRsct_TerminalConnect(Rsct_TerminalConnect* obj)
    { delete obj; }
    static int Connect(Rsct_TerminalConnect* obj, int _port)
    { return obj->Connect(_port); }
    // follow the pattern for Update & Disconnect
    BOOL CheckDownloadmode(Reader* _pReader);
    void Init();
    void Terminate();
    Rsct_TerminalManager* m_pTerminalManager;       
// in C# you would call createNew to first get a Rsct_TerminalConnect object pointer
// I am skipping delegate declarations, and LoadLibrary + GetProcAdress here.
IntPtr connectorObj = createNew();
int connectResult = Connect(connectorObj, portNumber);

Open in new window


Author Comment

ID: 22928933
Ok I understand that it's no more trivial to do.
I've access to some demo code in C++ how to use the DLL not to the source of the DLL itself.
And if I understand you right you suggest to write a wrapper in C++ for using the DLL right?
This is my problem as I'm not able to code in C++.
Reading and translate it to an other (NET) language is almost ok  or modify a little bit, too - but never done any project in C++.

Well as I think I wouldn't write a compiler in this life the other method sounds great but more difficult than learning a little bit of C++ ....

So the only solution is to do the wrapper in C++?

Accepted Solution

jhshukla earned 2000 total points
ID: 22935203
C++ wrapper is one of the good options.
(1) You don't modify class definitions. Don't have to recompile.
(2) All wrapper code is in one place and so easily manageable.
(3) you don't have to have access to source code.
Con: Takes a little effort to setup the project correctly.
Honestly speaking, I have not needed to write such wrapper.

Other good option for small projects is to add static methods as in the example above.
Pro: Not much thinking is needed. You could even write a script to do the job for you.
(1) Maintainable only for small projects. Say up to about 10-20 classes and a total of up to 200-250 public methods. Those are arbitrary numbers so don't take my word for it.
(2) Needs access to source code.
(3) Need to recompile DLLs and all projects that load those DLLs statically. Figuring out which ones you need to recompile will be a royal PITA.

It's your choice which way to go.

Author Closing Comment

ID: 31515025
I think I've to learn some more C++ :-) Thanks at all

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

We all know that functional code is the leg that any good program stands on when it comes right down to it, however, if your program lacks a good user interface your product may not have the appeal needed to keep your customers happy. This issue can…
This article is for Object-Oriented Programming (OOP) beginners. An Interface contains declarations of events, indexers, methods and/or properties. Any class which implements the Interface should provide the concrete implementation for each Inter…
The viewer will learn how to use and create keystrokes in Netbeans IDE 8.0 for Windows.
The viewer will learn how to use and create new code templates in NetBeans IDE 8.0 for Windows.

578 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question