String Assignment not working for C++ DLL - Urgent!

Hi Guys - I'm literally pulling my hair out over this one.

I'm having an issue with string assignment in my unmanaged C++ code. Everything works fine without the C++/CLI wrapper and the C# GUI. However, the string is just not being assigned to what it should be. I've created a very small app to demonstrate this.

These are the source and header files of the unmanaged c++ app:

Test.h

#pragma once
#define DllExport __declspec( dllexport )

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <map>
#include <stdexcept>
#include "TestConstantsHeader.h"

namespace DataVerifier
{
class DllExport CDataVerifier
{
public:
CDataVerifier();
~CDataVerifier();

//! @brief A function that processes the messages
void Process();
};
}

TestConstantsHeader.h

#pragma once
#define DllExport __declspec( dllexport )

#include <iostream>

namespace DataVerifier
{
namespace Structure
{
const std::string strHTMLTemplate = "<doctype html>"
"<html lang=\"en\">"
"<head>"
"<meta charset=\"utf-8\"/>"
"<title>Data Verifier Test Results - {@testdesc}</title>"
"<style>"
"body {"
"\tbackground: none repeat scroll 0 0 #F3F3F4;"
"\tcolor: #1E1E1F;"
"\tfont-family: \"Segoe UI\",Tahoma,Geneva,Verdana,sans-serif;"
"\tmargin: 0;"
"\tpadding: 0;"
"}"
"h1 {"
"\tbackground-color: #E2E2E2;"
"\tborder-bottom: 1px solid #C1C1C2;"
"\tcolor: #201F20;"
"\tfont-size: 21pt;"
"\tfont-weight: normal;"
"\tmargin: 0;"
"\tpadding: 10px 0 10px 10px;"
"}"
"h2 {"
"\tfont-size: 18pt;"
"\tfont-weight: normal;"
"\tmargin: 0;"
"\tpadding: 15px 0 5px;"
"}"
"h3 {"
"\tbackground-color: rgba(0, 0, 0, 0);"
"\tfont-size: 15pt;"
"\tfont-weight: normal;"
"\tmargin: 0;"
"\tpadding: 15px 0 5px;"
"}"
"a {"
"\tcolor: #1382CE;"
"}"
"table {"
"\tborder-collapse: collapse;"
"\tborder-spacing: 0;"
"\tfont-size: 10pt;"
"}"
"table th {"
"\tbackground: none repeat scroll 0 0 #E7E7E8;"
"\tfont-weight: normal;"
"\tpadding: 3px 6px;"
"\ttext-align: left;"
"\ttext-decoration: none;"
"}"
"table td {"
"\tbackground: none repeat scroll 0 0 #F7F7F8;"
"\tborder: 1px solid #E7E7E8;"
"\tmargin: 0;"
"\tpadding: 3px 6px 5px 5px;"
"\tvertical-align: top;"
"}"
""
".textCentered {"
"\ttext-align: center;"
"}"
".messageCell {"
"\twidth: 100;"
"}"
"#content {"
"\tpadding: 0 12px 12px;"
"}"
"#overview table {"
"\tmax-width: 75;"
"\twidth: auto;"
"}"
"#messages table {"
"\twidth: 97;"
"}"
"</style>"
"</head>"
"<body>"
"<div id=\"big_wrapper\">"
"\t<h1>Test Results - {@testdesc}</h1>"
"\t<table>"
"{@eeddata}"
"\t</table>"
"</body>"
"</html>";
}
}

Test.cpp

#include "Test.h"

using namespace DataVerifier;

CDataVerifier::CDataVerifier()
{
}

CDataVerifier::~CDataVerifier(){}

void CDataVerifier::Process()
{
std::string strTmp = Structure::strHTMLTemplate;
std::cout << strTmp;
}

My TestCLR.h Class Library (CLR)

// TestCLR.h

#pragma once
#include <stdexcept>

#include "../Test1/Test.h"
#include "../Test1/TestConstantsHeader.h"

using namespace System;
using namespace DataVerifier;

namespace TestCLR {

public ref class Class1
{
public:
Class1();
~Class1();
// TODO: Add your methods for this class here.
void CheckStringAssignment();

CDataVerifier *dv;
};
}

TestCLR.cpp

// This is the main DLL file.

#include "stdafx.h"

#include "TestCLR.h"

TestCLR::Class1::Class1()
{
dv = new CDataVerifier();
}

TestCLR::Class1::~Class1()
{}

void TestCLR::Class1::CheckStringAssignment()
{
dv->Process();
}

Main.cpp (in the unmanaged C++ app)

#include <iostream>

#include "Test.h"

int main()
{
return 0;
}

And finally, the C# GUI code:

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 Test1GUI
{
public partial class Form1 : Form
{
Class1 cs = new Class1();
public Form1()
{
InitializeComponent();
cs.CheckStringAssignment();
}
}
}

If I go into CheckStringAssignment then Process (unmanaged code), I next the line where the assignment happens, and the string remains empty.

Any idea what might be going on?

Thanks
Don't know if my comments will help, and I don't do C++ CLI, but you said you were desperate (or pulling your hair out or whatever), so I'll try.

You do realize that strings in object oriented languages are objects, don't you? In other words, they aren't data primitives like integers or floats which the hardware directly supports. In my mind its very unlikely that C++ CLI, which I'm assumming uses the .NET framework, knows anything about std::string, which is a C++ Standard Library specific object. std::string isn't even a part of C++; its in the Standard Library. In terms of myself, I don't even use it. Years ago I wrote my own String Class and I use that.

So I'd actually find it somewhat surprising if I had an unmanaged C++ dll that exported functions or classes that exposed std::string, and a .NET host was able to deal with it.
A) Your code is rather difficult to read as it's unformatted. Could you please tag and (if necessary) reformat it (esp. the indentation!)

"How to use code tags"
http://www.cplusplus.com/articles/jEywvCM9/

B) I don't see an assignment in your demo? So I have no idea which string remains empty!

But it appears to do as expected -- when I run the C# app a string is written out to the console.

Note that I created a C# console app, not a Forms app. If you C# app was a Forms app then you'd only see the string output by Test.dll if you created a console for the process.

(Your unmanaged C++ app does nothing so I didn't bother with it. Was it supposed to be something like

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include "../Test1/Test.h"

// assuming MSVC
#pragma comment(lib, "test.lib")

int main()
{
    using namespace DataVerifier;

    CDataVerifier dv;
    dv.Process();

    return 0;
}


??)

Andy

PS Regarding

std::string isn't even a part of C++; its in the Standard Library.

I think this depends on where you think the borders are. As std::string is part of the C++ Standard Library I think it is part of C++ (in the broader sense.)

Of course, it's not a built-in (or primitive) type, so it's not part of the core language.

So I'd actually find it somewhat surprising if I had an unmanaged C++ dll that exported functions or classes that exposed std::string, and a .NET host was able to deal with it.

That's the point of TestCLI -- it provides a .NET interface to the native C++ "Test" DLL. C++/CLI can interface with native C++ DLLs as well as .NET assemblies.

Last edited on
Topic archived. No new replies allowed.