Click here to Skip to main content
15,893,814 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hoping someone could help. This is my first time calling a C++ DLL from C#. I do know about wrapping it in an extern "C" to prevent mangling and I am aware that the main cause of the error I am getting is recursion. I do not see where my code could cause recursion. This might be an issue with me allocating a stack reserve size in the properties of my DLL to handle my string buffer in one of the functions.
This is a Codepage detecting DLL in C++ being called from C#. There are only 2 functions and the first has been tested and works fine (DetectCodePage.)
The second will convert a given string from one codepage to another.

The DLL code is as follows:
C++
extern "C"
{
	CPFUNCSDLL_API INT DetectCodePage(CHAR *inString, INT inStrLen) {
		DetectEncodingInfo dei[20];
		DetectEncodingInfo *pdei = dei;
		INT len = inStrLen;
		INT dei_cnt = 20;
		INT rtn = -1;
		HRESULT hr;
		IMultiLanguage2* pIM2;
		hr = CoCreateInstance(CLSID_CMultiLanguage,	// CLSID of coclass
			NULL,				  // not used - aggregation
			CLSCTX_INPROC_SERVER, // type of server
			IID_IMultiLanguage2,  // IID of interface
			(void**)&pIM2);		  // Pointer to our interface pointer
		if (SUCCEEDED(hr)) {
			rtn = -2;
			hr = pIM2->DetectInputCodepage(MLDETECTCP_NONE, 0, inString, &len, pdei, &dei_cnt);
			if (SUCCEEDED(hr)) {
				if (pdei[0].nCodePage == 20127)
					rtn = 1252;
				else
					rtn = pdei[0].nCodePage;
			}
			pIM2->Release();
		}
		return rtn;
	}

	CPFUNCSDLL_API INT ConvertCodePage(CHAR *inString, UINT inStrLen, CHAR *outString, UINT outStrLen, INT cpin, INT cpout) {
		if (cpin == 0) {
			cpin = DetectCodePage(inString, inStrLen);
		}
		if (cpin == cpout) {
			strcpy_s(inString, inStrLen, outString);
			return 0;
		}
		UINT len = inStrLen;
		DWORD mode2U = 0;
		DWORD modeFU = 0;
		HRESULT hr;
		IMultiLanguage2* pIM2;
		CHAR ubuff[1048576];
		UINT max1 = 1048576;
		UINT max2 = 1048576;
		INT rtn = -1;
		hr = CoCreateInstance(CLSID_CMultiLanguage,	// CLSID of coclass
			NULL,				  // not used - aggregation
			CLSCTX_INPROC_SERVER, // type of server
			IID_IMultiLanguage2,  // IID of interface
			(void**)&pIM2);		  // Pointer to our interface pointer
		if (SUCCEEDED(hr)) {
			rtn = -2;
			if (pIM2->ConvertStringToUnicode(&mode2U, cpin, inString, &len, (WCHAR *)ubuff, &max1) != E_FAIL &&
				pIM2->ConvertStringFromUnicode(&modeFU, cpout, (WCHAR *)ubuff, &max2, outString, &outStrLen) != E_FAIL) {
				rtn = 0;
			}
			pIM2->Release();
		}
		return rtn;
	}
}


The imports in my C# code are:
C#
[DllImport("CPFuncsDLL", CharSet = CharSet.Ansi, SetLastError = true)]
 public static extern int DetectCodePage(String inString, int inStrLen);

 [DllImport("CPFuncsDLL", CharSet = CharSet.Ansi, SetLastError = true)]
 public static extern int ConvertCodePage(String inString, int inStrLen, StringBuilder outString, int outStrLen, int cpin, int cpout);


The C# code to test the second function is:

C#
String check = "THIS IS SOME TEXT";
StringBuilder output = new StringBuilder(check.Length * 4);
int checklen = check.Length;
int result = ConvertCodePage(check, checklen, output, checklen * 4, 0, 65001);
MessageBox.Show("Result = " + result.ToString() + "\r\nIn = '" + check + "'\r\nOut = '" + output + "'", "Codepage");

Actually in this case it should return the same string because the ASCII text is the same as the UTF-8 text.


*************************

I do not see anyplace in ConvertCodePage where I'm doing anything recursive. Maybe the "CHAR ubuff[1048576];" line is the cause but maybe I'm too dumb to know how to properly allocate enough memory on the stack to handle the memory I wish to use. Or maybe I'm supposed to be allocating enough space in the calling program... but tried that.

Any help would be greatly appreciated.

Thanks
Posted
Updated 14-Jul-14 0:23am
v2

Quote:
CHAR ubuff[1048576]

That looks indeed your problem because, by default, the thread stack size is 1MB. You may either
  • Use dynamic memory allocation.

or
 
Share this answer
 
You are passing a StringBuilder for your char *outString parameter.

I really don't think that will work. A StringBuilder is NOT a String, or char* or char[].

Matthew
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900