2

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");
            }
        }
4
  • what is the declaration of JmsStatus::JsonMsgStatus? Is it accessible from C#? Commented Jan 6, 2015 at 21:07
  • The status is an enum list. I do not believe it is accessible from the C# since buried in the original static lib, thus why I call the open/close and just look for an integer return. Commented Jan 6, 2015 at 21:12
  • Then the return type of jmcOpen and jmcClose should be int as the enum is not accessible from C#. Commented Jan 6, 2015 at 21:15
  • Okay, tried that. Now the compiler is telling me that 'jmcOpen' is not supported by the language. What does that mean for the open call now? Commented Jan 6, 2015 at 21:28

1 Answer 1

1

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 );
   } 
Sign up to request clarification or add additional context in comments.

9 Comments

I tried your updates as noted, yet the inclusion of the <msclr\marshal_cppst.h> opened up a ton of new 'errors' in ws2def.h, winsock2.h, ws2ipdef.h, etc. I am guessing my DLL is calling upon items with the static library thad conflict with adding this inclusion at this level. Kind of like the order in which Windows.h and Winsock.h are included cause problems. Any ideas to work around this without having to recreate the static library?
Try this: stackoverflow.com/questions/17789807/…; which doesn't require that header file.
That appears to work for me. Allow me to step through some code before officially closing this out. Thanks again for your responses.
In that I have just been trying to get this all to compile, I tried to step into the C# program to see how the DLL calls flow. In doing this, I now get a "A first chance exception of type 'System.Windows.Markup.XamlParseException' occurred in PresentationFramework.dll" exception error to pop up before the first line of (C#) codes is exercised. In further investigation, if the line of "jmcDll jmClient = new jmcDll();" is removed (and other related calls to the wrapped DLL (jmcDLL), the exception goes away. Is something not setup correctly to utilize the wrapped DLL?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.