【问题标题】:Why does my code error when the tutorial I used does not have an error at all?当我使用的教程完全没有错误时,为什么我的代码会出错?
【发布时间】:2019-03-12 02:01:36
【问题描述】:

我一个字一个字地关注 this 教程,但由于某种原因,我收到以下错误:

" 1>c:\users\fish's ocean\source\repos\dll1\dll1\dll1.cpp(47): 错误 C2664: 'bool (ds_map,char *,double)': 无法将参数 2 从 ' const char [5]' 到 'char *' "

也在第 48 和 49 行。

This 是我的 Visual Studio 在这些行上的样子,但由于某种原因,教程没有错误,我无法弄清楚其中的区别(他在 17 分钟左右的某个地方越过了这些行)

// Dll1.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include <thread>
#include <chrono>
#include <vector>
#include <mutex>

#define gmx extern "C" __declspec(dllexport)

using ds_map = int;
using thread = std::thread;
using milliseconds = std::chrono::milliseconds;

const int EVENT_OTHER_SOCIAL = 70;

void(*gml_event_perform_async)(ds_map map, int event_type) = nullptr;
int(*gml_ds_map_create)(int n, ...) = nullptr;
bool(*gml_ds_map_add_double)(ds_map map, char* key, double value);
bool(*gml_ds_map_add_string)(ds_map map, char* key, char* value);

std::mutex thread_key;

std::vector<thread*> threads;
std::vector<uint32_t> open_slots;

gmx double RegisterCallbacks(char * arg1, char* arg2, char* arg3, char* arg4) {
gml_event_perform_async = (void(*)(ds_map, int))arg1;
gml_ds_map_create = (int(*)(int, ...))arg2;
gml_ds_map_add_double = (bool(*)(ds_map, char*, double))arg3;
gml_ds_map_add_string = (bool(*)(ds_map, char*, char*))arg4;
return 0;
}

ds_map ds_map_create() {
return gml_ds_map_create(0);
}

void return_double(double time, double type, double value, int handle) {
long t = (long)time;
std::this_thread::sleep_for(milliseconds(t));

thread_key.lock();

ds_map map = ds_map_create();
gml_ds_map_add_double(map, "type", type);
gml_ds_map_add_double(map, "value", value);
gml_ds_map_add_double(map, "handle", handle);
gml_event_perform_async(map, EVENT_OTHER_SOCIAL);

thread_key.lock();
}

gmx double thread_create(double time, double type, double value) {
int index;

thread_key.lock();

if (open_slots.empty()) {
    index = threads.size();
    threads.push_back(new thread(return_double, time, type, value, index));
}
else {
    index = open_slots.back();
    open_slots.pop_back();
    threads[index] = new thread(return_double, time, type, value, index);
}

thread_key.unlock();
return index;
}

gmx double thread_kill(double index) {
thread_key.lock();

if (threads.size() > index && threads[index] != NULL) {
    if (threads[index]->joinable()) {
        threads[index]->detach();
    }
    delete threads[index];
    threads[index] = NULL;
    open_slots.push_back(index);
}
thread_key.unlock();
return 1;
}

gmx double thread_free(double index) {
thread_key.lock();

if (threads.size() > index && threads[index] != NULL) {
    if (threads[index]->joinable()) {
        threads[index]->join();
    }
    delete threads[index];
    threads[index] = NULL;
    open_slots.push_back(index);
}
thread_key.unlock();
return 1;
}

【问题讨论】:

  • 我想说gml_ds_map_add_double..._add_string 的声明需要有一个const char* 作为第二个参数。但是我不知道图书馆,所以我不知道这是否正确。
  • 这会导致“1>c:\users\fish's ocean\source\repos\dll1\dll1\dll1.cpp(31): error C2440: '=': cannot convert from 'bool (__cdecl *)(ds_map,char *,double)' 到 'bool (__cdecl *)(ds_map,const char *,double)'”(以及第 32 行的类似错误)
  • 这是一个 const 正确性的问题。您无法删除 const:即您无法将 const char * 转换为 char *,因为您可以更改它,从而违反 const。

标签: c++ gml


【解决方案1】:

您的教程似乎很古老。很久以前,一些编译器允许将字符串 - "type" 传递给需要 char * 的参数,或者将这些值分配给 char * 变量。 (字符串不被视为常量。)

这已更改为字符串是恒定的(并且是只读的)。这意味着函数、函数指针和原型中的大多数(如果不是全部)char * 参数需要更改为 const char * 才能使用您正在使用的字符串。但是,这意味着用作回调的函数也需要更改其签名。

并且RegisterCallbacks 应该为所有参数采用正确的函数原型,而不是将它们作为char * 值接受。如今,实现这一目标所需的强制转换很容易导致未定义行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-13
    • 1970-01-01
    • 2016-09-18
    相关资源
    最近更新 更多