Reputation: 41
I have a static library written in C++ that I wanted to access via my C# program. This library includes multiple classes. In my research and workings, I developed a CLR DLL wrapper for the static library to access the class methods (open and close). All successful until I tried to call one of the 'public' functions from the DLL. I receive the f(x)
is inaccessible due to its protection level when trying to compile the C# project. f(x)
in this case points to JsonMsgClientDll.jmcDll.jmClientClose()
and JsonMsgClientDll.jmcDll.jmcOpen()
. I have searched other rags to not find anything similar to what I have run into. Any help here would be great. Just a note that of the multiple classes of the static library, I am only trying to port (wrapper) the most basic (open/close) of functions to get it working firstly. All is made public and thus cannot figure out why they are not accessible.
I have listed the necessary code snippets below. The jsonmsgservice
namespace is the static library reference where the class is JsonMsgClient
. The output of the jmcDLL.cpp
is a DLL named JsonMsgClientDll.dll
. The noted DLL is referenced properly in the C# project.
jmcDLL.cpp
#include <vcclr.h>
#include "JmsClientConnector.h"
#include "JmsStatus.h"
#include "JsonMsgClient.h"
using namespace System;
using namespace jsonmsgservice;
namespace JsonMsgClientDll
{
public ref class jmcDll
{
public:
// constructor
jmcDll()
{
_myJsonMsgClient = new JsonMsgClient();
}
// destructor
~jmcDll()
{
delete _myJsonMsgClient;
}
// open a connection
JmsStatus::JsonMsgStatus jmcOpen(string ipAddr)
{
return _myJsonMsgClient->SessionOpen(ipAddr);
}
// close a connection
JmsStatus::JsonMsgStatus jmClientClose()
{
return _myJsonMsgClient->SessionClose();
}
private:
JsonMsgClient * _myJsonMsgClient;
};
}
C# Main Window.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.IO.Ports;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using JsonMsgClientDll;
namespace JTC_GUI
{
public partial class MainWindow : Window
{
...
int sockFd = 0;
string ipAddress = "";
uint msgIdVal = 0;
jmcDll jmClient = new jmcDll();
public MainWindow()
{
...
}
private void clientOpenButton_Click(object sender, RoutedEventArgs e)
{
ipAddress = ipAddrInput.Text;
if (...)
...
else
{
// attempting to call wrappered C++ code to open a connection
int jmcStatus = jmClient.jmcOpen(ipAddress);
if (sockFd > 0)
{
...
private void clientCloseButton_Click(object sender, RoutedEventArgs e)
{
if (jmClient.jmClientClose() == 0)
{
...
}
else
{
MessageBox.Show("The connection FAILED to close or was never opened");
}
}
Upvotes: 2
Views: 765
Reputation: 6050
In the C++/CLI code:
JmsStatus::JsonMsgStatus jmcOpen(string ipAddr)
{
return _myJsonMsgClient->SessionOpen(ipAddr);
}
The type of the function parameter is string, which is a native C++ type, while in your C# code, you call this function with a System.String paramter, which is a reference type, so the conversion need to be done here.
The function should be like this:(assuming you're using std)
#include <msclr\marshal_cppstd.h>
JmsStatus::JsonMsgStatus jmcOpen(System::String^ ipAddr)
{
std::string unmanaged = msclr::interop::marshal_as<std::string>(ipAddr);
return _myJsonMsgClient->SessionOpen(unmanaged );
}
Upvotes: 1