由于cdecl和myclass冲突,出现错误C2664

由于cdecl和myclass冲突,出现错误C2664,class,visual-c++,cdecl,c2664,Class,Visual C++,Cdecl,C2664,我正在尝试将C中的一段旧代码加入到我当前的VC++项目中: // .h class DMSinv : public CDialog { double finte(double z); double ITFStolz(double Zp1, double Zp2, double Zc); }; // .cpp double Zcglob; double DMSinv::finte(double z) { re

我正在尝试将C中的一段旧代码加入到我当前的VC++项目中:

// .h
    class DMSinv : public CDialog {
        double finte(double z);
        double ITFStolz(double Zp1, double Zp2, double Zc);
    };

// .cpp
    double Zcglob;
    double DMSinv::finte(double z) 
    {
       return TFStolz(z, Zcglob);
    }

    double DMSinv::ITFStolz(double Zp1, double Zp2, double Zc)
    {
        int ierr;
        Zcglob = Zc;

        return (coteglob(&DMSinv::finte, Zp1, Zp2, 1.0e-10, &ierr));
    //error C2664: 'DMSinv::coteglob' : cannot convert parameter 1 from 'double (__thiscall DMSinv::* )(double)' to 'double (__cdecl *)(double)'    

    }
coteglob函数来自旧的C部分,finte是将TFStolz函数传递给coteglob的中间函数

我在论坛中搜索并发现了以下相关问题: 我试着用这种方式申请:

// .h
    class DMSinv : public CDialog {
        virtual double finte(double z);
        double ITFStolz(double Zp1, double Zp2, double Zc);
    };

// .cpp
    double Zcglob;
    extern "C"
    {
        static double __cdecl finteHelper(double z)
        {
            DMSinv* datainv = reinterpret_cast< DMSinv > (z); //error C2440: 'reinterpret_cast' : cannot convert from 'double' to 'DMSinv'  

            datainv->finte(z);
        }
    }

    double DMSinv::ITFStolz(double Zp1, double Zp2, double Zc)
    {
        int ierr;
        Zcglob = Zc;
        double solution = coteglob(&finteHelper, Zp1, Zp2, 1.0e-10, &ierr);
        return solution;
    }
/.h
DMSIV类:公共CDialog{
虚拟双芬特(双z);
双ITFStolz(双Zp1、双Zp2、双Zc);
};
//.cpp
双Zcglob;
外部“C”
{
静态双\uu cdecl finteHelper(双z)
{
DMSinv*datainv=reinterpret_cast(z);//错误C2440:“reinterpret_cast”:无法从“double”转换为“DMSinv”
datainv->finte(z);
}
}
双DMSIV::ITFStolz(双Zp1、双Zp2、双Zc)
{
内特里尔;
Zcglob=Zc;
双解决方案=coteglob(&finteHelper、Zp1、Zp2、1.0e-10和ierr);
回流液;
}
但仍然不起作用。有人能指导我如何适应它吗?我还是个新手,这似乎与我的知识相去甚远


提前谢谢

我认为你不能这样做。您需要以某种方式将引用传递给对象(
this
)。在链接问题中,函数的参数被定义为type
void*
,因此您可以向函数传递任何需要的信息,包括指向
this
的指针。您的函数接受双精度,因此无法将此传递给它

我认为最简单的方法是在类外定义中间函数,因为它似乎独立于类内部。大概是这样的:

double finte(double z) 
{
   return TFStolz(z, Zcglob);
}

您还可以将实例指针存储在静态函数可以读取的公共全局/静态类内变量中。

不确定是否可以按需要执行操作。我想到的唯一选择是使用一些静态变量来存储DMSinv对象的地址。这将限制您使用简单实现的1个线程

试试这个:

// .h
class DMSinv : public CDialog {
    double finte(double z);
    double ITFStolz(double Zp1, double Zp2, double Zc);

private:
  static DMSinv* _current;
  static double __cdecl finteHelper(double z);
};

// .cpp
double Zcglob;
DMSinv* DMSinv::_current = 0;
double DMSinv::finte(double z) 
{
   return TFStolz(z, Zcglob);
}

double DMSinv::ITFStolz(double Zp1, double Zp2, double Zc)
{
    int ierr;
    Zcglob = Zc;

   _current = this;
   return (coteglob(DMSinv::finteHelper, Zp1, Zp2, 1.0e-10, &ierr));
}

double __cdecl DMSinv::finteHelper(double z)
{
    return _current->finte(z);
}
在国际海事组织,这不是一个好的解决方案,但我不确定是否还有其他办法

PS 要消除一个线程的限制,可以使用TLS插槽,也可以在VC++中使用。 对于后者,只需将
\u declspec(thread)
添加到
\u current
中,如下所示:
static\u declspec(thread)DMSinv*\u current。但是请注意,进程的每个线程变量的数量是有限的。请在MSDN中阅读更多相关内容

更新

Disclamer:只是为了好玩


理论上,还有其他机会。可以将程序集代码存储在数组中,并附加到对象。这个汇编代码应该是一个uu cdecl函数,它根据eip寄存器将u cdecl转换为u thiscall。但这永远不应该发生…:D

DMSinv*datainv=reinterpret_cast(z)
-您不应该转换到
DMSinv*
?我已经尝试过了,但这给了我同样的错误:
错误C2440:“reinterpret_cast”:无法从“double”转换为“DMSinv*”
这似乎是一个简单而干净的解决方案,但TFStolz是DMSinv类的一个功能,因此,如果finte不在类中,则它无法识别TFStolz:
错误C3861:'TFStolz':未找到标识符
。也许finte中的指针包含TFStolz。。。我必须重新考虑一下,正如我说的,我是一个新手,对这个问题不太放心。谢谢为什么它要求我在finiteHelper中返回一个值,当它是静态的时是否有必要<代码>错误C4716:“DMSinv::finteHelper”:必须返回一个值
。感谢
\uu declspec(thread)
,看起来很有趣,我会看看。我已经更新了我的代码来修复这个错误。只需添加returnas,编译器会问你。好的,谢谢,现在它编译了,但没有运行,在某个点中断。我会继续研究为什么会发生这种情况,正如你所说,这可能不是最好的解决方案,但谢谢你的帮助!!我再次更新了我的代码。看起来您刚刚获得了空指针访问权限。已将当前分配移动到其他函数。不过,还有一个警告。若对coteglob的调用是异步的(即,当主线程运行时,它将在一段时间后返回),那个么您就会遇到问题。您需要等待此coteglob调用回调才能将finiteHelper用于DMSinv的其他实例。非常感谢denis bu,感谢您的帮助和解释,使其更易于理解,这真的超出了我的范围,很抱歉延迟回答,我正在出差