0

I have C++ code below:

someclass* my = new someclass();
my->doSomething();

delete my;

It just works perfect when I call this class from another C++ project.

But when I call it from C#, it gives me an error and I cannot trace the error.

This is how I call c++ dll from C#.

[DllImport(@"Helper.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.BStr)]
private static extern string LoginQuery(string UserID, string UserPW, string ProxyServer, StringBuilder Cookies);

This is C++ code.

extern "C" FUNCDLL_API BSTR LoginQuery(const char* UserID, const char* UserPW, const char* ProxyServer, char Cookies[])
{
    someclass* my = new someclass();
    std::string ret    my->doSomething();

    delete my;  --> here, I get error when called from C#.

    return ::SysAllocString(CComBSTR(ret.c_str()).Detach());
}

Can somebody explain the reason?

EDIT The LoginQuery returns some result from class.

EDIT I changed my codes.

EDIT The error message is something like below. It is translated from Korean to English.

Additional Information: Critical error occured during runtime. Error address is 0x6799bd26(thread 0x2860). Error code is 0xc0000005. This error can be part of but which is not safe or CLR, or it can be unconfirmed part of user code. Nomarlly the reason of this error is COM-interop or marshaling error, and it can destroy stack.

If there is a handler for this exception, the program may be safely continued.

Joshua Son
  • 1,839
  • 6
  • 31
  • 51
  • It doesn't work perfectly; it has a memory leak. Why wouldn't you just do `someclass my; my.doSomething();`? – chris Mar 22 '14 at 00:37
  • @chris What do you mean by that? Do you mean my codes have some memory leak? Call you tell me where? Actually I am newbie to C++. – Joshua Son Mar 22 '14 at 00:38
  • As soon as you change where the pointer points to, that memory will never be seen again. – chris Mar 22 '14 at 00:40
  • I edited some of my question, actually the function returns me some strings and I am deleting the class not the string. So, I have nothing to lose. And the codes work perfect when I call it from another c++ project. – Joshua Son Mar 22 '14 at 00:45
  • When you set a pointer to NULL, delete is no more called on the pointer (and neither does it point to any valid memory).The memory it was pointing to doesn't get deleted. – vaibhav kumar Mar 22 '14 at 00:47
  • @vaibhavkumar Maybe, my codes make people confused. I am still having problem when delete class, not setting it NULL. Okay, I won't worry about setting it NULL, but I cannot delete my class instance when it's called from C#. – Joshua Son Mar 22 '14 at 00:49
  • 4
    "...It just works perfect" No, it doesn't. `delete NULL` is perfectly acceptable by the language standard, and is effectively a no-op. You may as well have just: `my = NULL;`, and I honestly have a hard time seeing how `my = new Something;` followed by `my = NULL;` is *not* an obvious emory leak in the context of this code. (And an `std::string` is no `BSTR`, so I'm surprised this even *compiles*). – WhozCraig Mar 22 '14 at 00:50
  • @JoshuaSon See if this helps http://stackoverflow.com/a/5698663/1866301. I personally always used C++/CLI if I wanted to use both C++ & C# code. – vaibhav kumar Mar 22 '14 at 00:54
  • @WhozCraig I have edited my code, get rid of setting my class NULL. std::string returns BSTR type, I don't know. I just read from MSDN. – Joshua Son Mar 22 '14 at 00:59
  • 1
    Why you are using Cdecl instead of StdCall.:: – Alessandro D'Andria Mar 22 '14 at 01:00

1 Answers1

0

You need to delete my before assigning it to null.

In addition it appears that you're returning a std::string, whereas the return type is a BSTR.

In addition try changing your dllimport line to:

[DllImport(@"Helper.dll", EntryPoint="LoginQuery", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]

R M
  • 96
  • 1
  • 4