Basic C# GUI crashes in main - c#

I have a very basic unmanaged C++ project, C++/CLI wrapper and C# GUI. I've built all 3 projects as x64. I try and run the C# project and I get the following exception:
First-chance exception at 0x000007fefd84cacd in TestAppGUI.exe:
Microsoft C++ exception: EEFileLoadException * __ptr64 at memory
location 0x0057b498.
Does anyone know what could be causing the issue?
These are my classes:
Test.h (unmanaged code)
#define DllExport __declspec( dllexport )
#include <iostream>
namespace Test
{
class DllExport BasicTest
{
public:
BasicTest();
~BasicTest();
};
}
Test.cpp
#include "Test.h"
Test::BasicTest::BasicTest()
{
}
Test::BasicTest::~BasicTest()
{
}
TestCLR.h (wrapper)
// TestCLR.h
#pragma once
#include "../TestApp/Test.h"
using namespace System;
using namespace Test;
namespace TestCLR {
public ref class Class1
{
// TODO: Add your methods for this class here.
public:
Class1();
private:
BasicTest *bsTest;
};
}
TestCLR.cpp
// This is the main DLL file.
#include "stdafx.h"
#include "TestCLR.h"
TestCLR::Class1::Class1()
{
bsTest = new BasicTest();
}
TestAppGUI Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using TestCLR;
namespace TestAppGUI
{
public partial class Form1 : Form
{
Class1 obj = new Class1();
public Form1()
{
InitializeComponent();
}
}
}

Related

Calling C# COM DLL from C++

The C++ code is as follows
#include "stdafx.h"
#include <Windows.h>
#import "C:\shreyas\Documents\ConsoleApplication1\ConsoleApplication1\bin\Debug\ConsoleApplication1.tlb" no_namespace
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
IMyClassPtr obj;
//iProgramPtr obj;
obj.CreateInstance(__uuidof(MyClass));
printf("value: %d",obj->display());
CoUninitialize();
getchar();
return 0;
}
The C# code is as follows
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace demo
{
[ComVisible(true)]
public interface IMyClass
{
int display();
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
class MyClass : IMyClass
{
public int display()
{
Console.WriteLine("Hello");
return 10;
}
}
}
I would like to call the C# display function from C++ code. I have done the required settings in C# project properties. In the code obj.CreateInstance(__uuid(MyClass)); the MyClass is giving an error as an undefined identifier.
Do pay attention to the build warning you get when you compile ConsoleApplication1:
warning MSB3214: "C:...\ConsoleApplication1\bin\Debug\ConsoleApplication1.dll" does not contain any types that can be registered for COM Interop.
That's not good of course. Also something you see with you look at the .tlb file with Oleview.exe's View + Typelib command. Or open the .tlh file that the #import directive generates with a text editor, find it back in the C++ project's Debug directory. You'll see that MyClass is completely missing, thus the compile error.
That is because of:
class MyClass : IMyClass
You forgot to declare it public. Required.

C++/CLI namespace does not exist error

I have a problem with my code writed in C++/CLI. I have an 'WidowsFormApplication': a namespace with this name does not exist error in file Database.h. I tried almost everything, and searched in web for an answer, but i can't. What is wrong with my code? Code is down below. Thanks.
short review of "form1.h":
#ifndef Form1_h
#define Form1_h
#include"Database.h"
namespace WindowsFormApplication{
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
/// <summary>
/// Summary for Form1
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
private: System::Windows::Forms::MenuStrip^ menuStrip1;
private: System::Windows::Forms::ToolStripMenuItem^
"database.h":
#ifndef Database_h
#define Database_h
#include"Form1.h"
namespace Database{
using namespace System::Collections::Generic;
using namespace WindowsFormApplication;//error
public ref class Column{
private: List<System::Windows::Forms::TextBox^> ^columnName;
private: int numberOfColumn;
private: int x;
private: int tabIndex;
private: int width;
private: Form1^ mainFrame;//also error becouse of namespace
public: Column(Form1^ mainFrame);//and error
public: void push_back();
public: void click();
};
}
#endif
You are including "Form1.h" in "Database.h" and "Database.h" in "Form1.h". Are you sure you want to do this?

SEHException with simple DLL

I am currently trying to use a simple C++ DLL in a C# program for a school project but I have trouble making the DLL and Program link with each other. When I try to call the DLL's function in the main program, I get a SEHExcpetion thrown from the DLL.
Here is the DLL code
#include <stdio.h>
#include <string>
using namespace std;
extern "C"
{
__declspec(dllexport) string Crypter(string sIn)
{
return sIn+ " from DLL";
}
}
And here's the C# code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
[DllImport("CryptoDLL2.dll")]
public static extern string Crypter(string sIn);
public Form1()
{
InitializeComponent();
}
private void BTN_Crypter_Click(object sender, EventArgs e)
{
TB_OUT.Text = ("");
TB_OUT.Text = Crypter(TB_IN.Text); //exception thrown here
}
}
}
Strings in C# and C++ - Those are completely different types, layouts, etc. And you expect them to work.
Check out char* with marshalling.
you cannot use std::string from C#, it is a c++ class, .NET does not know how to handle it.
Try using wchar_t* or BSTR.
I did a test to make sure the linking was fine, here is a sample app showing it does work.
#include <stdio.h>
#include <string>
using namespace std;
extern "C"
{
__declspec(dllexport) string Crypter(string sIn)
{
printf("test");
return "from DLL";
}
}
And
public class Test
{
[DllImport("TestDll.dll")]
public static extern string Crypter(string sIn);
static void Main(string[] args)
{
Console.WriteLine(Crypter("a"));
}
}
This prints me out
test
followed by a newline.
You need to probably marshal the data from c++ to .net, or use a c++/clr managed dll which would make things easier on you.

Calling C# method within a Java program

C# methods cannot be called directly in Java using JNI due to different reasons. So first we have to write a wrapper for C# using C++ then create the dll and use it through JNI in Java.
I have problem in calling C# code in C++. I'm adding C# .netmodule file to a C++ project. Code is pasted below. Please guide me if i'm doing anything wrong.
This is my managed C++ class UsbSerialNum.h:
#using <mscorlib.dll>
#include <iostream>
#using "UsbSerialNumberCSharp.netmodule"
using namespace std;
using namespace System;
public __gc class UsbSerialNum
{
public:
UsbSerialNumberCSharp::UsbSerialNumberCSharp __gc *t;
UsbSerialNum() {
cout<<"Hello from C++";
t = new UsbSerialNumberCSharp::UsbSerialNumberCSharp();
}
void CallUsbSerialNumberCSharpHello() {
t->hello();
}
};
C# UsbSerialNumberCSharp.cs file from which i've created the .netmodule file:
using System.Collections.Generic;
using System.Text;
namespace UsbSerialNumberCSharp
{
public class UsbSerialNumberCSharp
{
public UsbSerialNumberCSharp(){
Console.WriteLine("hello");
}
public static void hello()
{
Console.WriteLine("hello");
}
public void helloCSharp ()
{
Console.WriteLine("helloCSharp");
}
}
}
Here is my main makeDLL.cpp file from which makeDLL.dll is created:
#include "jni.h"
#include <iostream>
// This is the java header created using the javah -jni command.
#include "testDLL.h"
// This is the Managed C++ header that contains the call to the C#
#include "UsbSerialNum.h"
using namespace std;
JNIEXPORT void JNICALL Java_testDLL_hello
(JNIEnv *, jobject) {
// Instantiate the MC++ class.
UsbSerialNum* serial = new UsbSerialNum();
serial->CallUsbSerialNumberCSharpHello();
}
Here is my java class:
public class testDLL {
static {
System.loadLibrary("makeDLL");
}
/**
* #param args
*/
public static void main (String[] args) {
// new testDLL().GetUSBDevices("SCR3", 100);
new testDLL().hello();
}
public native void hello();
}
EDIT:
If i simply ignore the call to UsbSerial.h in my main file i.e. use simple C++ then my code is working fine in Java. Basically C++ managed class is not working properly.
Please guide me. Thanks.
It would be useful to know what you need this interoperability for exactly. In any case, you should look into IKVM; alternatively you can (as has been suggested for a similar problem) use COM as a bridge: expose the C#/CLR as a COM interface and then use com4j in Java.
You can avoid C# and still can query WMI using C++ only. See Using WMI to call method on objects

Returning Struct from VC++ to C#

I have written a structure in VC++. I have made a dll of the VC++ code and calling this dll in C# using PInvoke.
The VC++ dll looks like this
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <iostream>
#if defined(_MSC_VER)
#include <windows.h>
#define DLL extern "C" __declspec(dllexport)
#else
#define DLL
#endif
struct SYSTEM_OUTPUT
{
int status;
};
DLL SYSTEM_OUTPUT* getStatus()
{
SYSTEM_OUTPUT* output;
output->status = 7;
return output;
}
I am calling the getStatus() function from the dll in my C# code, which looks as follows;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace UsingReturnStructDLL
{
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEM_OUTPUT
{
[MarshalAs(UnmanagedType.I4)]
int Status;
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public SYSTEM_OUTPUT output;
[DllImport("ReturnStructDLL", EntryPoint = "getStatus")]
[return: MarshalAs(UnmanagedType.Struct)]
public extern static SYSTEM_OUTPUT getStatus();
private void button1_Click(object sender, EventArgs e)
{
try
{
SYSTEM_OUTPUT output = getStatus();
}
catch (AccessViolationException e)
{
label1.Text = e.Message;
}
}
}
}
I want to retrieve the values in the struct in my C# code. With the above setup of my code, I am getting the following error;
Cannot marshal 'return value': Invalid managed/unmanaged type combination (Int32/UInt32
must be paired with I4, U4, or Error).
Can someone please help me with the issue?
Thanks.
Make your C++ code work first. It is junk as posted, you don't initialize the pointer. It will crash with an AccessViolation.
Returning pointers to structures is very hard to get right in C/C++ as well, the client of your code won't know how the memory needs to be released. Which plays havoc on the P/Invoke marshaller as well, it is going to try to release the pointer with CoTaskMemFree(). That's a kaboom on Vista and up, a memory leak on XP.
All of these problems disappear if you let the client pass a pointer to the structure as an argument:
void getStatus(SYSTEM_OUTPUT* buffer)
Which then in C# becomes:
[DllImport("mumble.dll")]
private static extern void getStatus(out SYSTEM_OUTPUT buffer);

Categories