1
votes

I need to create a dll that works with callback function. When I set Runtime Libary = Multi-threaded Debug (/ MTd) in project properties, it generates this error message:

enter image description here

But when I set Runtime Libary = Multi-threaded Debug DLL (/ MDd), the application works perfectly

Look at my DLL:

callbackproc.h

#include <string>

#ifdef CALLBACKPROC_EXPORTS
#define CALLBACKPROC_API __declspec(dllexport)
#else
#define CALLBACKPROC_API __declspec(dllimport)
#endif

// our sample callback will only take 1 string parameter
typedef void (CALLBACK * fnCallBackFunc)(std::string value);

// marked as extern "C" to avoid name mangling issue
extern "C"
{
    //this is the export function for subscriber to register the callback function
    CALLBACKPROC_API void Register_Callback(fnCallBackFunc func);
}

callbackpro.cpp

#include "stdafx.h"
#include "callbackproc.h"
#include <sstream>

void Register_Callback(fnCallBackFunc func)
{
    int count = 0;

    // let's send 10 messages to the subscriber
    while(count < 10)
    {
        // format the message
        std::stringstream msg;
        msg << "Message #" << count;

        // call the callback function
        func(msg.str());

        count++;

        // Sleep for 2 seconds
        Sleep(2000);
    }
}

stdafx.h

#pragma once

#include "targetver.h"    
#define WIN32_LEAN_AND_MEAN           
// Windows Header Files:
#include <windows.h>

My application that consumes a dll

#include <windows.h>
#include <string>

#include "callbackproc.h"

// Callback function to print message receive from DLL
void CALLBACK MyCallbackFunc(std::string value)
{
    printf("callback: %s\n", value.c_str());
}

int _tmain(int argc, _TCHAR* argv[])
{
    // Register the callback to the DLL
    Register_Callback(MyCallbackFunc);

    return 0;
}

Where am I going wrong? Tanks!

1
Did you press "Retry" (Repetir) to debug the application? What did you discover?Drew Dormann
Please specify the runtime specication (MTd,MDd) for both your app and DLLShmil The Cat
I get another error = Exoression _pFristBlock == pHead and applying follows the flow. but when the function and call again we went back to the same problemmsantiago
You're copying a std::string across a compilation unit (transitional from your application to the DLL). Unless both are built with identical build configurations, you're hosing yourself. Remember, the standard library does not have a formal ABI. Odds are very likely your application is being built with /MDd (using the multi-threaded debug DLL runtime). If your DLL is not identically built, you're using two different heap managers and shooting yourself in the foot. Don't pass standard library objects across PE transitions.WhozCraig

1 Answers

4
votes

Seems to me as a classic problem of passing std types (in this case std::string) across DLL boundaries.

As a best practice, pass only "native" data types across DLL boundaries, I'm sure in 99% that if you change your prototype from

typedef void (CALLBACK * fnCallBackFunc)(std::string value);

to

typedef void (CALLBACK * fnCallBackFunc)(const char* value);

Your code will work regardless of your underlying runtime