- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在寻找具体信息来解决我的问题,但我认为它太具体了。我正在开发一个项目,它以一种非常令人困惑的方式混合了 C 和 C++ 代码。最后,我不得不获取一些 C 代码并将其用于用 C++ 编译的文件中。我虽然它可以进行一些更改,但我发现了一个我无法自己解决的错误。这是关于线程的使用。
我已经将两个函数声明为公开的,因为我收到了它们,并在我的头文件 drviRIOAD_1D.h
中声明了它们,在我的类(class)drviRIOAD_1D
:
void ai_pv_thread(void *p);
void aiDMA_thread(void *p);
然后我将其代码复制到我的 cpp 文件 drviRIOAD_1D.cpp 中:(我只包含有错误的代码部分)
void drviRIOAD_1D::aiDMA_thread(void *p){
ai_pv_publish= (irio_dmathread_t*) malloc(sizeof(irio_dmathread_t)*irioPvt->DMATtoHOSTNCh[ai_dma_thread->id]);
buffersize=irioPvt->DMATtoHOSTBlockNWords[ai_dma_thread->id];
samples_per_channel=irioPvt->DMATtoHOSTBlockNWords[ai_dma_thread->id]*8; //Bytes per block
samples_per_channel= samples_per_channel/irioPvt->DMATtoHOSTSampleSize[ai_dma_thread->id]; //Samples per block
samples_per_channel= samples_per_channel/irioPvt->DMATtoHOSTNCh[ai_dma_thread->id];//Samples per channel per block
// Ring Buffers for Waveforms PVs
ai_dma_thread->IdRing= (void**) malloc(sizeof(epicsRingBytesId)*irioPvt->DMATtoHOSTNCh[ai_dma_thread->id]);
// Creation and Launching of threads working as consumers for EPICS PVs publishing
aux=(float**) malloc(sizeof(float*)*irioPvt->DMATtoHOSTNCh[ai_dma_thread->id]);
for(i=0;i<irioPvt->DMATtoHOSTNCh[ai_dma_thread->id];i++){
aux[i]=(float*) malloc(sizeof(float)*samples_per_channel);
if(ch_nelm[chIndex+i]!=0){
ai_dma_thread->IdRing[i]=epicsRingBytesCreate(samples_per_channel*irioPvt->DMATtoHOSTSampleSize[ai_dma_thread->id]*4096);//!<Ring buffer to store manage the waveforms.
ai_pv_publish[i].IdRing=&ai_dma_thread->IdRing[i];
ai_pv_publish[i].dma_thread_name=(char *)malloc(40);
sprintf(ai_pv_publish[i].dma_thread_name,"%sPVPublisher%02d",ai_dma_thread->dma_thread_name,i);
ai_pv_publish[i].id=i; //channel identifier
ai_pv_publish[i].dmanumber=ai_dma_thread->id; //dma identifier
ai_pv_publish[i].threadends=0;
ai_pv_publish[i].endAck=0;
ai_pv_publish[i].asynPvt=ai_dma_thread->asynPvt;
ai_pv_publish[i].dma_thread_id=epicsThreadCreate(ai_pv_publish[i].dma_thread_name,
epicsThreadPriorityHigh,epicsThreadGetStackSize(epicsThreadStackBig),
(EPICSTHREADFUNC)ai_pv_thread,
(void *)&ai_pv_publish[i]); //Here occurs the error, it means that ai_pv_thread argument does not work properly
}
最后一行给了我一个错误,如下:
../drviRIOAD_1D.cpp:1846: error: invalid use of member (did you forget the ‘&’ ?)
这是函数 ai_pv_thread(void *p)
void drviRIOAD_1D::ai_pv_thread(void *p){
//There is one thread per ringbuffer (per DMA channel)
irio_dmathread_t *pv_thread;
pv_thread=(irio_dmathread_t *)p;
irioDrv_t *irioPvt = &pv_thread->asynPvt->drvPvt;
float* pv_data;
int pv_nelem=4096,aux;
while (irio_threadsrun==0) {usleep(10000);}
aux=irioPvt->DMATtoHOSTChIndex[pv_thread->dmanumber]+pv_thread->id;
printf ("ch_nelm %d\n", ch_nelm[aux]);
pv_nelem=ch_nelm[aux];
pv_data = (float*) malloc(sizeof(float)*pv_nelem);
do{
int NbytesDecimated;
NbytesDecimated=epicsRingBytesUsedBytes(*pv_thread->IdRing);
if(NbytesDecimated>=(sizeof(float)*pv_nelem))
{
if(epicsRingBytesIsFull(*pv_thread->IdRing)){
//TODO: Error
}
epicsRingBytesGet(*pv_thread->IdRing,(char*)pv_data,sizeof(float)*pv_nelem);
CallAIInsFloat32Array(pv_thread->asynPvt,CH,
irioPvt->DMATtoHOSTChIndex[pv_thread->dmanumber]+pv_thread->id,pv_data,pv_nelem);
}else{
//@todo: fix this
usleep(10000);
}
}while (pv_thread->threadends==0);
free(pv_data);
free(pv_thread->dma_thread_name);
pv_thread->endAck=1;
}
我不明白的是为什么会出现错误,因为这段代码已经可以工作了。我认为这是因为迁移,但我无法解决它。
事实上,我有一个 cpp 的近示例,我一直在使用它,但没有结果。在本例中,他们使用静态回调创建了线程,该回调位于调用类内部函数的类外部。不同的是,类内部函数的参数是 void
, void callbackTask()
就我而言是 void ai_pv_thread(void *p)
.
给我带来问题的函数来自外部API,它提供了C接口(interface)和C++接口(interface),也许这也是一个问题?我认为我没有正确访问我的函数 ai_pv_thread,它是在没有参数的情况下调用的,但实际上它需要一个 void *p。不过,我尝试了一些更改,例如添加 '::' (EPICSTHREADFUNC)::ai_pv_thread 但在这种情况下,编译器告诉我错误:'::ai_pv_thread' 未声明。
有人可以向我解释一下 C 和 C++ 中的回调之间的区别,以便我可以解释这种行为吗?我必须做出什么改变才能让它发挥作用?我可以更改函数参数,例如静态或函数的位置,现在它们在类 drviRIOAD_1D 中是公共(public)的,但我可以将它们取出。
这是link to this API (只是为了了解函数epicsThreadCreate的api):
epicsThreadCreate
--> 创建一个新线程。优先级和 stackSize 参数的使用取决于实现。某些实现可能会忽略其中一个或另一个,但为了可移植性,应该为两者指定适当的值。作为 stackSize 参数传递的值应通过调用 epicsThreadGetStackSize
获得。 funptr 参数指定实现线程的函数,parm 是传递给 funptr 的单个参数。当 funptr 返回时,线程终止。
它的界面:
epicsThreadId epicsThreadCreate(const char *name,
unsigned int priority, unsigned int stackSize,
EPICSTHREADFUNC funptr,void *parm);
最佳答案
假设 ai_pv_thread(void*)
是一个成员函数,那么您所做的就是未定义的行为。鉴于您遇到的错误,我倾向于这么认为。至start a thread using a member function you need to use a helper像这样:
static void pv_thread_start(void* in)
{
if(!in)
{
return;
}
std::unique_ptr<data_holder> holder(static_cast<data_holder*>(in));
holder->obj->ai_pv_thread(holder->data);
}
或者,您可以使用静态成员函数,但其语法很奇怪,我通常会避免使用它。
创建线程时,您可能需要传入一个具有 *this
和您需要的数据的 POD 对象,如下所示:
struct data_holder{
drviRIOAD_1D* obj;
ai_pv_publish* data;
};
在创建线程时:
auto data = std::make_unique<data_holder>({this, &ai_pv_publish[i]});
epicsThreadCreate(
ai_pv_publish[i].dma_thread_name,
epicsThreadPriorityHigh,
epicsThreadGetStackSize(epicsThreadStackBig),
// this cast is probably unncessary now
static_cast<EPICSTHREADFUNC>(pv_thread_start),
static_cast<void*>(data.release());
关于c++ - 尝试将线程创建方法从 C 迁移到 C++ 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34251831/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!