MSVC C++ Name Mangling From String On Runtime

六月ゝ 毕业季﹏ 提交于 2021-01-28 05:41:02

问题


First i will start with the reason i need name mangling on runtime.

I need to create a bridge between dll and its wrapper

namespace Wrapper
{
    class  __declspec(dllexport) Token
    {
    public:

        virtual void release() {}
    };
}

class  __declspec(dllexport) Token
{
public:

    virtual void release(){}
};

The idea is to use dumpin to generate all the mangled names of the dll holding class token and than demangled them.

?release@Token@@UAEXXZ --> void Token::release(void)

after that i want to convert is to match the Wrapper so i will need to change the function name

void Token::release(void) --> void Wrapper::Token::release(void)

and then i need to mangle it again so i can create a def file that direct the old function to the new one.

?release@Token@@UAEXXZ = ?release@Token@Wrapper@@UAEXXZ

all this process needs to be on run time.

First and the easiest solution is to find a function that mangle strings but i couldn't find any...

any other solution?


回答1:


The Clang compiler is ABI-compatible with MSVC, including name mangling. The underlying infrastructure is part of the LLVM project, and I found llvm-undname which demangles MSVC names. Perhaps you can rework it to add the Wrapper:: namespace to symbols and re-mangle.

You can find inspiration about mangling names in this test code.




回答2:


If you are allowed to change the DLL, I'd usually use a different approach, by exporting extern "C" getter function (that does not mangle thus doesn't need demangling) and using virtual interface to access the class (note that the virtual interface doesn't need to be dllexported then). Your Token interface seems to be virtual anyway.

Something along those lines (not tested, just to show the idea):

DLL access header:

class Token  // notice no dllexport!
{
protected:
    // should not be used to delete directly (DLL vs EXE heap issues)
    virtual ~Token() {}
    virtual void destroyImpl() = 0; // pure virtual
public:
    static inline void destroy(Token* token) {
        // need to check for NULL otherwise virtual call would segfault
        if (token) token->destroyImpl();
    }
    virtual void doSomething() = 0; // pure virtual
};

extern "C" __declspec(dllexport) Token * createToken();

DLL implementation:

class TokenImpl: public Token
{
public:
    virtual void destroyImpl() {
        delete this;
    }
    virtual void doSomething() {
        // implement here
    }
};

extern "C" __declspec(dllexport) Token * createToken()
{
    return new TokenImpl;
}

Usage:

// ideally wrap in RAII to be sure to always release
// (e.g. can use std::shared_ptr with custom deleter)
Token * token = createToken();

// use the token
token->doSomething();

// destroy
Token::destroy(token);

With shared::ptr (can also create a typedef/static inline convenience creator function in the Token interface):

std::shared_ptr<Token> token(createToken(),
                             // Use the custom destroy function
                             &Token::destroy);
token->doSomething()
// token->destroy() called automatically when last shared ptr reference removed

This way you only need to export the extern-C creator function (and the release function, if not part of the interface), which will then not be mangled thus easy to use via the runtime loading.



来源:https://stackoverflow.com/questions/55159432/msvc-c-name-mangling-from-string-on-runtime

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!