Valhalla Legends Forums Archive | .NET Platform | [Managed C++] System::Array* of String* -> char** ?!

AuthorMessageTime
shadypalm88
I'm trying to build a .NET wrapper for BNCSutil, and this is the first time I've worked with Managed Extensions for C++.  First I'm starting with the CheckRevision functions.  To do this, I've created a __gc class CheckRevision, the constructor of which takes some arguments, runs checkRevision() and getExeInfo() and stores their results in properties that can be accessed by the application.  Its signature is:
[code]CheckRevision(Array* files, String* valueString, CheckRevision::Platforms platform, int mpqNumber);[/code]

I'm trying to go from the array files into a char** or char*[] to pass to checkRevision, and I'm having a lot of trouble and causing the compiler to feverishly spit errors at me.  Can anyone shed some light on how I'm incorrectly approaching this:

[code]CheckRevision::CheckRevision(Array* files, String* valueString, CheckRevision:Platforms platform, int mpqNumber)
{
    unsigned char c_files __gc[] __gc[];
    Collections::IEnumerator* enu;
    int i = 0, res;
    unsigned char c_valueString __gc[];
    unsigned long checksum;
    uint32_t version;
    char exeInfo[512];
    char* cp_ValueString;

    c_files = __gc new unsigned char __gc[] __gc[files->Length];
    enu = files->GetEnumerator();
    while (enu->MoveNext()) {
         String* str;
         try {
              str = __try_cast<String*> (enu->get_Current());
         } catch (InvalidCastException* e) {
              throw new ArgumentException(S"files", S"The files array must contain System.Strings only.");
         }
         c_files[i] = Encoding:Default->GetBytes(str);
    }

c_valueString = Encoding:Default->GetBytes(valueString);
    cp_ValueString = __pin (char __gc*) &c_valueString[0];
    res = checkRevision(cp_ValueString, __pin (char __gc* __gc*) &c_files[0], files->Length, mpqNumber, &checksum);

    if (!res)
         throw new CheckRevisionException(S"checkRevision", S"Failed to get checksum of files.");

    m_checksum = (Int32) checksum;

    res = getExeInfo(__pin (char __gc*) &c_files[0][0], exeInfo, 512, &version, (int) platform);
    if (!res)
         throw new CheckRevisionException(S"getExeInfo", S"Failed to get executable version information.");

    m_version = (Int32) res;
    m_exeInfo = new String(exeInfo);
}[/code]

Some of the compiler's gripes:[code]error C2680: 'char __gc* __gc*': invalid target type for __try_case
error C2682: cannot use __try_cast to convert from 'System::Byte __gc *' to 'System::SByte __gc *'
error C2691: 'unsigned char __gc[]': invalid type for __gc array element[/code]
July 15, 2005, 9:24 PM
shadypalm88
Well I found my way around that problem but now the linker is complaining.[code]CheckRevision.obj : error LNK2001: unresolved external symbol "void __cdecl operator delete(void *)" (??3@$$FYAXPAX@Z)
CheckRevision.obj : error LNK2001: unresolved external symbol "void * __cdecl operator new(unsigned int)" (??2@$$FYAPAXI@Z)[/code]Explicitly telling the linker to load msvcrt.lib makes the errors go away but the DLL isn't created in the build folder.

Any ideas?
July 15, 2005, 10:33 PM
shadypalm88
Got it.  I followed the steps in this Microsoft knowledge base article and it built.
July 16, 2005, 8:09 PM

Search