CUDA和C++函数问题(Visual Studio 2013)

3
我将尝试把一个在cu文件中定义的cuda函数从Visual Studio的cpp文件中调用,但我一直收到以下错误信息。
TomColourCorrectionMain.obj : error LNK2019: unresolved external symbol "public: void __cdecl hwk::TomColourCorrection::brightness(int,int)" (?brightness@TomColourCorrection@hwk@@QEAAXHH@Z) referenced in function "public: virtual void __cdecl hwk::TomColourCorrection::processCore(class std::shared_ptr)" (?processCore@TomColourCorrection@hwk@@UEAAXV?$shared_ptr@VIImageProcessingContext@hwk@@@std@@@Z)
现在,根据阅读其他类似问题所了解,我明白这与函数的定义方式有关,以及其中存在问题,但当我在头文件和CUDA文件中定义时,我看不出问题所在。
以下是我的代码(我是CUDA的新手,但在不调用此C++函数时,我可以编译CUDA并运行代码):
头文件
#pragma once

#include "ImageProcessorWithProperties.h"
#include <iostream>
#include <cuda_runtime.h>
#include    <cuda.h>

class TomColourCorrection : public ImageProcessorWithProperties, public      PropertyConsumer<TomColourCorrection>{
public: TomColourCorrection(PropNodePtr n, std::function<void()> requestReprocess);

    virtual void processCore(IImageProcessingContextPtr context);

static void DeclareSettings(hwk::PropNodePtr n);

virtual ~TomColourCorrection();

void brightness(int iw, int ih); (function I am talking about)
};
 }

带有函数调用的cpp文件 //这只是重要代码的片段,其余部分对于实际函数本身并不必要

 #include "stdafx.h"
 #include "TomColourCorrection.h"

 #include <opencv2/imgproc/imgproc.hpp>
 #include <cv.h>
 #include <highgui.h>
 #include <opencv2/core/core.hpp>
 #include <opencv2/highgui/highgui.hpp>
 #include <iostream>

 #include <cuda_runtime.h>
 #include   <cuda.h>

 namespace hwk{ 

    TomColourCorrection::TomColourCorrection(PropNodePtr n, std::function<void()> requestReprocess) :
ImageProcessorWithProperties("sandbox", n, requestReprocess),
PropertyConsumer<TomColourCorrection>(n)
{

 }

void TomColourCorrection::processCore(IImageProcessingContextPtr context){



 brightness(16, 16); (just generic numbers at the moment as I am trying to resolve this issue etc)
    }
  }

CUDA文件和函数定义
#include "TomColourCorrection.h"
#include "device_launch_parameters.h"

__global__ void brightness_kernel(int iw, int ih)
{
// Calculate our pixel's location
int x = (blockIdx.x * blockDim.x) + threadIdx.x;
int y = (blockIdx.y * blockDim.y) + threadIdx.y;

// Variables to store the sum
int count = 0;
float sum = 0.0;

// Do the blur operation by summing the surround pixels
/*  for (int j = -(bh / 2); j <= (bh / 2); j++)
{
    for (int i = -(bw / 2); i <= (bw / 2); i++)
    {
        // Verify that this offset is within the image boundaries
        if ((x + i) < iw && (x + i) >= 0 && (y + j) < ih && (y + j) >= 0)
        {
            sum += (float)source[((y + j) * iw) + (x + i)];
            count++;
        }
    }
}*/

// Average the sum
sum /= (float)count;
//  dest[(y * iw) + x] = (unsigned char)sum;
}



void brightness(int iw, int ih) //, unsigned char *source, unsigned char *dest)
{
// allocate memory for the bitmap in GPU memory
unsigned char *dev_source, *dev_dest;
//  cudaHostGetDevicePointer(&dev_source, source, 0);
//  cudaHostGetDevicePointer(&dev_dest, dest, 0);

// Run the boxfilter kernel
dim3 blocks(iw / 16, ih / 16);
dim3 threads(16, 16);

// Execute the kernel
brightness_kernel << <blocks, threads >> >(iw, ih);
cudaThreadSynchronize();
}
2个回答

4

请按以下方式更改TomColourCorrection.h文件:

#pragma once

#include "ImageProcessorWithProperties.h"
#include <iostream>
#include <cuda_runtime.h>
#include    <cuda.h>

void brightness_wrapper(int, int);
class TomColourCorrection : public ImageProcessorWithProperties, public      PropertyConsumer<TomColourCorrection>{

  public: 
    TomColourCorrection(PropNodePtr n, std::function<void()> requestReprocess);

    virtual void processCore(IImageProcessingContextPtr context);

    static void DeclareSettings(hwk::PropNodePtr n);

    virtual ~TomColourCorrection();

    void brightness(int iw, int ih); 
};

按照以下方式修改您的cpp文件:

 #include "stdafx.h"
 #include "TomColourCorrection.h"

 #include <opencv2/imgproc/imgproc.hpp>
 #include <cv.h>
 #include <highgui.h>
 #include <opencv2/core/core.hpp>
 #include <opencv2/highgui/highgui.hpp>
 #include <iostream>

 #include <cuda_runtime.h>
 #include   <cuda.h>

 namespace hwk{ 

    void TomColourCorrection::brightness(int iw, int ih){
      brightness_wrapper(iw, ih);}

    TomColourCorrection::TomColourCorrection(PropNodePtr n, std::function<void()> requestReprocess) : ImageProcessorWithProperties("sandbox", n, requestReprocess),  PropertyConsumer<TomColourCorrection>(n)
      {

      }

    void TomColourCorrection::processCore(IImageProcessingContextPtr context){
        brightness(16, 16); 
    }
  }

并且在你的CUDA文件中更改这个:

void brightness(int iw, int ih) //, unsigned char *source, unsigned char *dest)

转换为:

void brightness_wrapper(int iw, int ih) //, unsigned char *source, unsigned char *dest)

这主要是阐述Ryck的答案的细节。


好的,问题已经解决了。有两个后续问题。
  1. 为什么这样可以工作?
  2. 我该如何实现第二个函数?我只需要添加另一个包装器吗?
- bardsleyta
主要问题就是Ryck所指出的:您的brightness函数被声明为类成员函数,但在定义函数时,您没有正确地将其作用域限定为类的成员。显然,使用适当的作用域进行定义可以通过多种方式处理,这个包装器方法只是一种可能的方法,因为它最大程度地减少了我对原始文件所做的键入修改量以进行演示。您应该能够针对任何一组函数重复此过程。 - Robert Crovella
好的。我现在明白了。非常感谢你和Ryck在这方面给予的帮助。我整个下午都在苦苦挣扎,很高兴你们帮我找到了解决方案。 - bardsleyta

2

我认为你需要进行改变。

void brightness(int iw, int ih)

为了

void TomColourCorrection::brightness(int iw, int ih)

并将实现移到您的头文件或.cpp文件中。


很遗憾,我已经尝试过了,但是我得到了相同的错误。 - bardsleyta
你可能想把brightness()变成一个普通的C函数。 - Rÿck Nöthing
然后调用cuda版本吗?问题是我需要将图像传递到cuda,因为我需要快速处理它,这就是为什么我需要使用cuda的原因。 - bardsleyta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接