2

I'm working on my first C++/CLI wrapper and am getting very confused wrt pointers. In the particular project I've got, I'm attempting to wrap an unmanaged C++ dll so I can use it in a C# app. Two objectives here: (1) to be able to use the library in my app, and (2) to learn to do this. Many hours of searching on this site and Google have yielded a bunch of answers that come close; I just can't seem to get all the way there. The unmanaged library I'm trying to incorporate is the key-value store "LevelDB" (I know of at least one .NET wrapper out there but, like I said, I'm trying to learn this).

The code below is the beginning of a CLI wrapper class written as if in unmanaged code. I.e. this, functionally, is what I'm trying to accomplish. Not surprisingly, this generates the following compiler error:

cannot convert parameter 3 from 'cli::interior_ptr<Type>' to 'leveldb::DB **'

When I began, I naively thought that I could/should replace the DB* pointer with a pinned pointer, something like

pin_ptr<leveldb::DB*> db

but this yields a similar error and doesn't work. Other combinations with interior pointers and handles (which, if I understand right, are not applicable here because the library is unmanaged) haven't worked either. I'd appreciate any advice pointing me in the right direction. Any references to good posts/articles would be great too but please include a word or two on how to adapt for my case since, after reading tons of them, I seem to be no closer. Thanks!

Example wrapping class:

#pragma once
#include "leveldb/db.h"

using namespace System;

namespace Wrapper
{
    public ref class DBWrapper 
    {
        leveldb::DB* db;

    public:
        DBWrapper()
        {
            leveldb::Options options;
            options.create_if_missing = true;
            leveldb::Status status = leveldb::DB::Open(options, "/tmp/testdb", &db);
        }

        ~DBWrapper() 
        {
            delete db;
        }
    };
}
1
  • Maybe inside a ref class, T* doesn't mean "pointer to T"? Just a guess... Commented Aug 18, 2012 at 18:19

1 Answer 1

4

Use a local variable:

DBWrapper()
{
    leveldb::Options options;
    options.create_if_missing = true;

    leveldb::DB* local_db(nullptr);
    leveldb::Status status =leveldb::DB::Open(options, "/tmp/testdb", &local_db);
    db = local_db;
}

The object under construction (pointed to by this) can be moved by the garbage collector, so a member variable does not have a fixed address.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes. I'm in a world of linker problems now but this answers my question. Obvious in retrospect. Thank you.

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.