I am traying to make use of Berkeley DB in C++/CLI with /clr mode. I authored this code:


// DB_test1.cpp : main project file.

#include "stdafx.h"
#pragma comment(lib,"libdb51")
using namespace System;
using namespace System::Runtime::InteropServices;

int main(array<System::String ^> ^args)
    Db SigDb(0,0);
    unsigned int oFlags= DB_CREATE;
    String^ HexSig="D8B1048900ABFF8B";
    wchar_t* a=( wchar_t* )Marshal::StringToHGlobalUni(HexSig).ToPointer() ;
    wchar_t* A=( wchar_t* )Marshal::StringToHGlobalUni(HexSig).ToPointer();;

    Dbt key1(&a,100);
    Dbt data1(&A,100);

    int ret= SigDb.put(NULL,&key1,&data1, DB_NOOVERWRITE);
        Console::WriteLine("You are trying to insert an exist key!");

    wchar_t DDData[200];
    Dbt getKey, getData;

        Console::WriteLine("Not Found !");
        Console::WriteLine(" {0}",Marshal::PtrToStringUni((IntPtr)DDData));

    return 0;

The code is put together effectively however it shows wrong output. I'm just traying to keep String^ HexSig="D8B1048900ABFF8B"; in SigDb.db after which directly browse the same string and print it!. The end result doesn't look like D8B1048900ABFF8B because it expected, however it seems like a random string. Any ideas?

After Editing: This segment of code is definitely performed Console::WriteLine("Not Found !");

I can tell two difficulties with the application:

1) The 2 calls to Marshal::FreeHGlobal are created prior to the items in the buffers are utilized. You should not free 'A' until following the put operation, and also you should not free 'a' until after both put and obtain procedures.

2) You're storing the pointers in Berkeley DB, as opposed to the strings themselves. That's because of the Dbt constructor calls. You are application is: Dbt key1(&a,100) It ought to be: Dbt key1(a, 100)

Similarly for that getKey.set_data method - it will make use of the pointer, not really a mention of pointer.

After I made the above mentioned changes for your application, it went not surprisingly.

Regards, Alex Gorrod Oracle Berkeley DB

You utilize Marshal::StringToHGlobalUni(), the converted string is really a wchar_t*, not really a char*. A large string using the Unicode codepoints encoded in utf16. To obtain a char* you'll need StringToHGlobalAnsi().

Do take into account that this can be a lossy conversion, dbase engines happen to be Unicode enabled for more than ten years now. Another serious issue is you don't release the memory allotted with this string, calling Marshal::FreeHGlobal() inside a finally block is needed. Additionally you should technically use GlobalLock() to transform the came back HGLOBAL to some pointer, consider Marshal::StringToCoTaskMemXxx.