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?
Related
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.
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();
}
}
}
I have a standalone c# applications that does something specific (listens to TCP port and pronounces all strings that arrive to it via speech synthesizer). How can I make the c# class visible to a VBA program, same way other "References" are visible to it? I would appreciate short and clean example. I struggle to find one of those for some reason.
If there are some gotchas specific to c# <-> vba interaction, I would like to know about those too.
Here is a C# code. I build is as a class library with "Register for COM interop" setting.
When I add the resulting .tlb file to VBA references list, I expect to see SayCom library that has SayCom class with 2 methods, square and getCount. I do not see that. What am I missing?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
[assembly: CLSCompliant(true)]
namespace SayCom
{
[CLSCompliant(true)]
[ComVisible(true)]
public class SayCom
{
int count;
public SayCom()
{
count = 0;
}
[ComVisible(true)]
public int square(int x)
{
++count;
return x * x;
}
[ComVisible(true)]
public int getCount()
{
return count;
}
}
}
This works for me
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace ClassLibrary1
{
[Guid("BBF87E31-77E2-46B6-8093-1689A144BFC6")]
[ComVisible(true)]
public interface MyMiniSubs
{
int square(int x);
int getCount();
}
[Guid("BBF87E31-77E2-46B6-8093-1689A144BFC7")]
[ClassInterface(ClassInterfaceType.None)]
public class Class1 : MyMiniSubs
{
int count;
public Class1()
{
count = 0;
}
[ComVisible(true)]
public int square(int x)
{
++count;
return x * x;
}
[ComVisible(true)]
public int getCount()
{
return count;
}
}
}
The only 'gotcha', as far as I know, is that your C# code needs to be CLS compliant. You should be able to follow the instructions here to import your C# code as a .dll into your VB application. Disclaimer: I have not tried this myself.
EDIT: Here's a more official MSDN reference that talks about calling functions from a .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.
I have a C# file A which defined some public enum and public struct. Now I need to define errorCode for them. I defined an enum named SubsystemErrorCode in file B. Both A and B don't have class inside. They are in the same namespace In one struct of file A, I try to use the SubsystemErrorCode enum but it give me error tell me :
Error 1 The type or namespace name 'SubsystemErrorCode' could not be found (are you missing a using directive or an assembly reference?)
If I move that SubsystemErrorCode into the same file. no error. But I really want them to be separated. How can I do this? thanks,
File A:
namespace SystemSoftware {
public struct StatusMessageBody {
public ProcessControlStatus State;
public StatVal LVP_OK;
public SubsystemErrorCode LVP_ERROR_CODE;
}
}
File B:
namespace SystemSoftware
{
//public class ErrorCode
//{
public enum SubsystemErrorCode : byte
{
NoError = 0,
EPCSS_CPU_ERROR = 1,
LVPS_ERROR
}
//}
}
The only reason for your problem is if the files, A and B, are not in the same project.
In this case the project that has the File A has to reference the project where File B is defined.
Think you are missing a USING statement or have not added a reference to the library.
Change your enum file to this
namespace SystemSoftware.Enums
{
public enum SubsystemErrorCode : byte
{
NoError = 0,
EPCSS_CPU_ERROR = 1,
LVPS_ERROR
}
}
and in your File A put this up the top (under using System;)
using SystemSoftware.Enums;
or you could asl try in File A
public SystemSoftware.Enums.SubsystemErrorCode LVP_ERROR_CODE;
instead of
public SubsystemErrorCode LVP_ERROR_CODE;
Edit: Forgot to say, I'm assuming that both File A and File B are in the same project?
If not, you will need a reference in Project A, to Project B
Ok Edit Again.
I Created Two Files, like you say, in the same project. It works, here they are.
File1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SystemSoftware
{
public struct StatusMessageBody
{
public SubsystemErrorCode LVP_ERROR_CODE;
}
}
File2.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SystemSoftware
{
//public class ErrorCode
//{
public enum SubsystemErrorCode : byte
{
NoError = 0,
EPCSS_CPU_ERROR = 1,
LVPS_ERROR
}
//}
}