Error when use C++ Library in C#

Hi,

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 ...?

Thanks,

Andre
C++:
 
// Library Class
 
class RSCT_TERMINALCONNECT_API Rsct_TerminalConnect 
{
public:
        // Konstruktion / Destruktion
                                                                Rsct_TerminalConnect(void);
        virtual                                         ~Rsct_TerminalConnect(void);
 
        // Verbindungshandling
                        int                                     Connect(int _port);
                        int                                     UpdateConnect(int _port, const char* _model);
                        int                                     Disconnect(int _port);
                         
 
protected:
                        BOOL                            CheckDownloadmode(Reader* _pReader);
 
private:
                        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());
 
C#:
    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

andre72Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jhshuklaCommented:
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 
{
public:
    Rsct_TerminalConnect(void);
    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
 
protected:
    BOOL CheckDownloadmode(Reader* _pReader);
 
private:
    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

0
andre72Author Commented:
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++?
0
jhshuklaCommented:
C++ wrapper is one of the good options.
Pros:
(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.
Cons:
(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.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
andre72Author Commented:
I think I've to learn some more C++ :-) Thanks at all
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Editors IDEs

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.