I'm desperately trying to make a dll with CUDA functions but I can't make it work.
I tried the method explained here :Creating DLL from CUDA using nvcc
to compile but I've got the following errors :
nvcc :
warning: __declspec attributes ignored
At line:1 char:1
+ nvcc -o ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (...ributes ignored:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
...\kernel.cu(81): warning: __declspec attributes ignored
...\cudaFFT.h(21): warning: __declspec attributes ignored
.../kernel.cu(81): warning: __declspec attributes ignored
nvcc warning : The 'compute_20', 'sm_20', and 'sm_21' architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning).
kernel.cu
CrÚation de la bibliothÞque C:/Users/alombet/Documents/Visual Studio 2015/Projects/Test/kernel.lib et de l'objet C:/Users/alombet/Documents/Visual Studio 2015/Projects/Test/kernel.exp
tmpxft_00003b9c_00000000-30_kernel.obj : error LNK2019: symbole externe non rÚsolu cufftPlan1d rÚfÚrencÚ dans la fonction AllocateMemoryForFFTs
tmpxft_00003b9c_00000000-30_kernel.obj : error LNK2019: symbole externe non rÚsolu cufftExecD2Z rÚfÚrencÚ dans la fonction ComputeFFT
tmpxft_00003b9c_00000000-30_kernel.obj : error LNK2019: symbole externe non rÚsolu cufftDestroy rÚfÚrencÚ dans la fonction DeAllocateMemoryForFFTs
C:/Users/alombet/Documents/Visual Studio 2015/Projects/Test/kernel.dll : fatal error LNK1120: 3 externes non rÚsolus
First of all the __declspec seems to be ignored, and after that it seems the compiler doesn't find the functions I use in the cuda libraries. I'm really not accustomed to compiling by hand. Usually, I rely on the IDE to do it and thus I am completely lost here.
Here is the code :
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <iostream>
// includes, system
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
// includes, project
#include <cuda_runtime.h>
#include <cufft.h>
#include <cufftXt.h>
#define LIBRARY_EXPORTS 1
#ifdef LIBRARY_EXPORTS
#define LIBRARY_API __declspec(dllexport)
#else
#define LIBRARY_API __declspec(dllimport)
#endif
#include "cudaFFT.h"
#ifdef __cplusplus
extern "C" {
#endif
int LIBRARY_API __cdecl numberOfGpus()
{
int nDevices;
cudaGetDeviceCount(&nDevices);
return nDevices;
}
cufftDoubleReal *host_input;
cufftDoubleReal *device_input;
cufftDoubleComplex *host_output;
cufftDoubleComplex *device_output;
cufftHandle plan;
cudaError LIBRARY_API __cdecl AllocateMemoryForFFTs(int maxSize, int maxBatch)
{
int width = maxSize; int height = maxBatch;
cudaError err = cudaMallocHost((void **)&host_input, sizeof(cufftDoubleReal) * width * height);
if (err)
return err;
err = cudaMallocHost((void **)&host_output, sizeof(cufftDoubleComplex) * (width / 2 + 1) * height);
if (err)
return err;
err = cudaMalloc((void **)&device_input, sizeof(cufftDoubleReal) * width * height);
if (err)
return err;
err = cudaMalloc((void **)&device_output, sizeof(cufftDoubleComplex) * (width / 2 + 1) * height);
if (err)
return err;
cufftResult res = cufftPlan1d(&plan, width, CUFFT_D2Z, height);
if (res)
return (cudaError)res;
return cudaSuccess;
}
double* LIBRARY_API __cdecl GetInputDataPointer()
{
return host_input;
}
cudaError LIBRARY_API __cdecl ComputeFFT(int size, int batch, double2** result)
{
cudaError err = cudaMemcpy(device_input, host_input, sizeof(cufftDoubleReal) * size * batch, cudaMemcpyHostToDevice);
if (err)
return err;
cufftResult res = cufftExecD2Z(plan, device_input, device_output);
if (res)
return (cudaError)res;
err = cudaMemcpy(host_output, device_output, sizeof(cufftDoubleComplex) * (size / 2 + 1) * batch, cudaMemcpyDeviceToHost);
if (err)
return err;
*result = host_output;
return cudaSuccess;
}
void LIBRARY_API __cdecl DeAllocateMemoryForFFTs()
{
cufftDestroy(plan);
cudaFree(device_input);
cudaFree(device_output);
cudaFreeHost(host_input);
cudaFreeHost(host_output);
}
#ifdef __cplusplus
}
#endif
Ok I found my problems, I leave the solution here in case it can help someone.
I removed the LIBRARY_API keyword from the .cu
In the .h I moved the LIBRARY_API at the very beginning of each declaration.
I changed the project properties in vs to generate a dll.
Let VS compile
Related
I'm trying to load a pcd file using pcl library, I do and show it using cloud viewer but I'm trying to use PCLVisualizer.
When I use addPointCloud function I have an error:
Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol "public: static class vtkMatrix4x4 * __cdecl vtkMatrix4x4::New(void)" (?New#vtkMatrix4x4##SAPEAV1#XZ) referenced in function "public: static class vtkSmartPointer __cdecl vtkSmartPointer::New(void)" (?New#?$vtkSmartPointer#VvtkMatrix4x4####SA?AV1#XZ) SamplePCL C:\Users\Nima_S_H\Documents\Visual Studio 2015\Projects\SamplePCL\SamplePCL\Source.obj 1
My codes:
#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_WARNINGS
#define _HAS_ITERATOR_DEBUGGING 0
#define _ITERATOR_DEBUG_LEVEL 0
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
void main()
{
typedef pcl::PointXYZRGB PTYPE;
pcl::PointCloud<PTYPE>::Ptr myCloudPtr(new pcl::PointCloud<PTYPE>);
if (pcl::io::loadPCDFile("e:/myCloudASCII.pcd", *myCloudPtr) == -1)
{
PCL_ERROR("Could not read PCD file.");
return;
}
pcl::visualization::PCLVisualizer viz;
viz.addPointCloud(myCloudPtr);
viz.spin();
}
this works for me.
Edit: actually it works even without the spinOnce . just use spin..
#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_WARNINGS
#define _HAS_ITERATOR_DEBUGGING 0
#define _ITERATOR_DEBUG_LEVEL 0
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
int main()
{
typedef pcl::PointXYZ PTYPE;
pcl::PointCloud<PTYPE>::Ptr myCloudPtr(new pcl::PointCloud<PTYPE>);
if (pcl::io::loadPCDFile("test.pcd", *myCloudPtr) == -1)
{
PCL_ERROR("Could not read PCD file.");
return 0;
}
pcl::visualization::PCLVisualizer viz;
viz.addPointCloud(myCloudPtr);
while (!viz.wasStopped ())
{
viz.spinOnce (100);
}
return 1;
}
I'm new in C++, I tried to copy this code and run in visual studio 2010. But it is giving unresolved extern 'c' error and another unresolved token "extern "C" as listed below the code.
This is the code causing the errors :
#ifdef _MANAGED // Works only with managed C++
#pragma once
#pragma managed(push, on)
#include <stdlib.h> //free
typedef void (__cdecl *_PVFV)(void);
extern "C" void * __cdecl _decode_pointer(void *);
extern "C" void * __cdecl _encoded_null();
// crtdll.c
extern "C" _PVFV *__onexitbegin;
extern "C" _PVFV *__onexitend;
void CrtDestroyStatics(void)
{
_PVFV * onexitbegin = (_PVFV *)_decode_pointer(__onexitbegin);
if (onexitbegin)
{
_PVFV * onexitend = (_PVFV *)_decode_pointer(__onexitend);
_PVFV function_to_call = NULL;
/* save the start and end for later comparison */
_PVFV * onexitbegin_saved = onexitbegin;
_PVFV * onexitend_saved = onexitend;
while (1)
{
_PVFV * onexitbegin_new = NULL;
_PVFV * onexitend_new = NULL;
/* find the last valid function pointer to call. */
while (--onexitend >= onexitbegin && (*onexitend == NULL || *onexitend == _encoded_null()))
{
/* keep going backwards. */
}
if (onexitend < onexitbegin)
{
/* there are no more valid entries in the list, we are done. */
break;
}
/* cache the function to call. */
function_to_call = (_PVFV)_decode_pointer(*onexitend);
/* mark the function pointer as visited. */
*onexitend = (_PVFV)_encoded_null();
/* call the function, which can eventually change __onexitbegin and __onexitend */
(*function_to_call)();
onexitbegin_new = (_PVFV *)_decode_pointer(__onexitbegin);
onexitend_new = (_PVFV *)_decode_pointer(__onexitend);
if ( ( onexitbegin_saved != onexitbegin_new ) || ( onexitend_saved != onexitend_new ) )
{
/* reset only if either start or end has changed */
__onexitbegin = onexitbegin_saved = onexitbegin_new;
__onexitend = onexitend_saved = onexitend_new;
}
break;
}
/*
* free the block holding onexit table to
* avoid memory leaks. Also zero the ptr
* variables so that they are clearly cleaned up.
*/
free ( onexitbegin ) ;
__onexitbegin = __onexitend = (_PVFV *)_encoded_null();
}
} //CrtDestroyStatics
#pragma managed(pop)
#endif
And here is the linker errors:
Error 4 error LNK2019: unresolved external symbol "extern "C" void * __cdecl _decode_pointer(void *)" (?_decode_pointer##$$J0YAPEAXPEAX#Z) referenced in function "void __cdecl CrtDestroyStatics(void)" (?CrtDestroyStatics##$$FYAXXZ)
Error 3 error LNK2028: unresolved token (0A000F2F) "extern "C" void * __cdecl _decode_pointer(void *)" (?_decode_pointer##$$J0YAPEAXPEAX#Z) referenced in function "void __cdecl CrtDestroyStatics(void)" (?CrtDestroyStatics##$$FYAXXZ)
Although I have those libraries values inherited for Additional Dependencies in Linker->Input
kernel32.lib
user32.lib
gdi32.lib
winspool.lib
comdlg32.lib
advapi32.lib
Please tell me what wrong I have committed?
If _decode_poiner is not available in your kernel32, it seems that your configuration is not correctly setup. If you had an older version of VS and upgraded, make sure that the linker doesn't point to the old environment.
You can check here for additional information on how to solve this.
I just completed a proof of concept, or so I thought, of feeding Microsoft Visual Studio 2010 some C++ code as a console program. The C++ code that compiled is given below:
#include "stdafx.h"
#include <stdio.h>
#include <Windows.h>
#include <stdlib.h>
#include <sndfile.h>
//The following libraries are related to parsing the text files
#include <iostream> //Open the file
#include <fstream> //Reading to and from files
//The following libraries are for conducting the DTW analysis
#include "dtw.h"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
printf("This is a test\n");
//This will be the length of the buffer used to hold samples while the program processes them.
//A SNDFILE is like FILE in a standard C library. Consequently, the sf_open_read and sf_open_write functions will return an
//SNDFILE* pointer when they successfully open the specified file.
SNDFILE* sf = NULL;
/*SF_INFO will obtain information of the file we wish to load into our program. */
SF_INFO info;
/*The following is descriptive information to obtain from wave files. These are declarations*/
int num_channels;
double num, num_items;S
double *buf;
int f, sr, c;
int i,j;
FILE *out;
/*This is where the program will open the WAV file */
info.format = 0;
sf = sf_open("C:\\Users\\GeekyOmega\\Desktop\\gameon.wav", SFM_READ, &info);
if(sf == NULL)
{
printf("Failed to open the file.\n");
getchar();
exit(-1);
}
/*Print some file information */
f = info.frames;
sr = info.samplerate;
c = info.channels;
/*Print information related to file*/
printf("frames = %d\n",f);
printf("sample rate = %d\n",sr);
printf("channels = %d\n",c);
/*Calculate and print the number of items*/
num_items = f*c;
printf("Read %lf items\n", num_items);
/*Allocate space for the data to be read*/
buf = (double *) malloc(num_items*sizeof(double));
num = sf_read_double(sf,buf,num_items);
sf_close(sf);
/*print the information*/
printf("Read %lf items\n", num);
/*Write the data to the filedata.out*/
out = fopen("filedata.txt", "w");
for(i = 0; i < num; i+=c)
{
for(j = 0; j < c; ++j)
{
fprintf(out, "%lf ", buf[i +j]);
}
fprintf(out,"\n");
}
fclose(out);
}
So next, and this is critical, I want this to work with a GUI. That is, I load in any file I want and it converts that wav file to text. I provide that code below:
#pragma once
//Libraries required for libsndfile
#include <sndfile.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
namespace WaveGui {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Runtime::InteropServices;
using namespace std;
/// <summary>
/// Summary for Form1
/// </summary>
I edited this for readability. It was a standard MSVS2010 form. I only added a button and open file dialog.
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
if(openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK)
{
//Note: Ask Gustafson how we might free the memory for this strign
// http://support.microsoft.com/?id=311259
char* str2 = (char*)(void*)Marshal::StringToHGlobalAnsi(openFileDialog1->FileName);
SNDFILE* sf = NULL;
SF_INFO info;
/*The following is descriptive information to obtain from wave files. These are declarations*/
int num_channels;
double num, num_items;
double *buf;
int f, sr, c;
int i,j;
FILE *out;
/*This is where the program will open the WAV file */
info.format = 0;
sf = sf_open(str2, SFM_READ, &info);
if(sf == NULL)
{
exit(-1);
}
/*Print some file information */
f = info.frames;
sr = info.samplerate;
c = info.channels;
/*Calculate and print the number of items*/
num_items = f*c;
/*Allocate space for the data to be read*/
buf = (double *) malloc(num_items*sizeof(double));
num = sf_read_double(sf,buf,num_items);
sf_close(sf);
/*Write the data to the filedata.out*/
out = fopen("filedata.txt", "w");
for(i = 0; i < num; i+=c)
{
for(j = 0; j < c; ++j)
{
fprintf(out, "%lf ", buf[i +j]);
}
fprintf(out,"\n");
}
fclose(out);
}
}
};
}
In the code for the button, I convert from a system string to regular string and then try to use the C++ code above to convert my wave file to txt information. I know the conversion code works, and I know the button code works as I have tested them separately. However, my library sndfile.h really dies when I try to use it now.
The error it gives me when I added the libraries stdio.h, Windows.H, stdlib.h, iostream, fstream is as follows:
1>WaveGui.obj : error LNK2031: unable to generate p/invoke for "extern "C" int __clrcall sf_close(struct SNDFILE_tag *)" (?sf_close##$$J0YMHPAUSNDFILE_tag###Z); calling convention missing in metadata
1>WaveGui.obj : error LNK2031: unable to generate p/invoke for "extern "C" __int64 __clrcall sf_read_double(struct SNDFILE_tag *,double *,__int64)" (?sf_read_double##$$J0YM_JPAUSNDFILE_tag##PAN_J#Z); calling convention missing in metadata
1>WaveGui.obj : error LNK2031: unable to generate p/invoke for "extern "C" struct SNDFILE_tag * __clrcall sf_open(char const *,int,struct SF_INFO *)" (?sf_open##$$J0YMPAUSNDFILE_tag##PBDHPAUSF_INFO###Z); calling convention missing in metadata
1>WaveGui.obj : warning LNK4248: unresolved typeref token (01000027) for 'SNDFILE_tag'; image may not run
1>WaveGui.obj : error LNK2028: unresolved token (0A000022) "extern "C" int __clrcall sf_close(struct SNDFILE_tag *)" (?sf_close##$$J0YMHPAUSNDFILE_tag###Z) referenced in function "private: void __clrcall WaveGui::Form1::button1_Click(class System::Object ^,class System::EventArgs ^)" (?button1_Click#Form1#WaveGui##$$FA$AAMXP$AAVObject#System##P$AAVEventArgs#4##Z)
1>WaveGui.obj : error LNK2028: unresolved token (0A000023) "extern "C" __int64 __clrcall sf_read_double(struct SNDFILE_tag *,double *,__int64)" (?sf_read_double##$$J0YM_JPAUSNDFILE_tag##PAN_J#Z) referenced in function "private: void __clrcall WaveGui::Form1::button1_Click(class System::Object ^,class System::EventArgs ^)" (?button1_Click#Form1#WaveGui##$$FA$AAMXP$AAVObject#System##P$AAVEventArgs#4##Z)
1>WaveGui.obj : error LNK2028: unresolved token (0A000025) "extern "C" struct SNDFILE_tag * __clrcall sf_open(char const *,int,struct SF_INFO *)" (?sf_open##$$J0YMPAUSNDFILE_tag##PBDHPAUSF_INFO###Z) referenced in function "private: void __clrcall WaveGui::Form1::button1_Click(class System::Object ^,class System::EventArgs ^)" (?button1_Click#Form1#WaveGui##$$FA$AAMXP$AAVObject#System##P$AAVEventArgs#4##Z)
1>WaveGui.obj : error LNK2019: unresolved external symbol "extern "C" int __clrcall sf_close(struct SNDFILE_tag *)" (?sf_close##$$J0YMHPAUSNDFILE_tag###Z) referenced in function "private: void __clrcall WaveGui::Form1::button1_Click(class System::Object ^,class System::EventArgs ^)" (?button1_Click#Form1#WaveGui##$$FA$AAMXP$AAVObject#System##P$AAVEventArgs#4##Z)
1>WaveGui.obj : error LNK2019: unresolved external symbol "extern "C" __int64 __clrcall sf_read_double(struct SNDFILE_tag *,double *,__int64)" (?sf_read_double##$$J0YM_JPAUSNDFILE_tag##PAN_J#Z) referenced in function "private: void __clrcall WaveGui::Form1::button1_Click(class System::Object ^,class System::EventArgs ^)" (?button1_Click#Form1#WaveGui##$$FA$AAMXP$AAVObject#System##P$AAVEventArgs#4##Z)
1>WaveGui.obj : error LNK2019: unresolved external symbol "extern "C" struct SNDFILE_tag * __clrcall sf_open(char const *,int,struct SF_INFO *)" (?sf_open##$$J0YMPAUSNDFILE_tag##PBDHPAUSF_INFO###Z) referenced in function "private: void __clrcall WaveGui::Form1::button1_Click(class System::Object ^,class System::EventArgs ^)" (?button1_Click#Form1#WaveGui##$$FA$AAMXP$AAVObject#System##P$AAVEventArgs#4##Z)
1>c:\users\geekyomega\documents\visual studio 2010\Projects\WaveGui\Debug\WaveGui.exe : fatal error LNK1120: 6 unresolved externals
As near as I can tell, I installed the library right. After all, it works perfectly fine with these libraries in a console situation. However, when I try to use the exact same code and libraries with my GUI form, it seems that the libraries are not playing nice with each other and as a result, I can't read my .h file right and access structs like SNDFILE.
Can someone please let me know what is going wrong? I have spent hours on this and I hope I don't have to scrap the libsndfile library. I really want to get it to work with MSVS2010, with the GUI and as far as I can tell, there is no reason this shouldn't be working. But you know what they say, computers don't lie.
As always, thanks for your patient help.
GeekyOmega
So, your console app is native code, but your GUI app is managed C++. Was that intentional, or did you intend for your GUI app to be native (Win32) code too?
I think you'll have better luck if you either go with 100% native code, or perhaps create a DLL to encapsulate your native code and call that via P/Invoke from your .NET GUI. Here's an example of using P/Invoke:
http://manski.net/2012/05/29/pinvoke-tutorial-basics-part-1/
I'm attempting to compile a simple C file for use with Mathematica. (Note: I did follow the rest of the instructions, creating the empty addtwotm.c file and adding addtwo.tm)
#include "mathlink.h"
extern int addtwo( int i, int j);
int addtwo( int i, int j)
{
return i+j;
}
#if WINDOWS_MATHLINK
#if __BORLANDC__
#pragma argsused
#endif
int PASCAL WinMain( HINSTANCE hinstCurrent, HINSTANCE hinstPrevious, LPSTR lpszCmdLine, int nCmdShow)
{
char buff[512];
char FAR * buff_start = buff;
char FAR * argv[32];
char FAR * FAR * argv_end = argv + 32;
hinstPrevious = hinstPrevious; /* suppress warning */
if( !MLInitializeIcon( hinstCurrent, nCmdShow)) return 1;
MLScanString( argv, &argv_end, &lpszCmdLine, &buff_start);
return MLMain( (int)(argv_end - argv), argv);
}
#else
int main(int argc, char* argv[])
{
return MLMain(argc, argv);
}
#endif
However, on build, I get this output:
1>------ Build started: Project: addtwo, Configuration: Debug Win32 ------
1> Performing Custom Build Tools
1> on "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\VC\bin\mprep.exe" "" -o "D:\Applications\Mathematica\SystemFiles\Links\MathLink\DeveloperKit\Windows\MathLinkExamples\addtwo\addtwo\..\addtwotm.c"
1>addtwo.obj : error LNK2019: unresolved external symbol _MLMain referenced in function _WinMain#16
1>addtwo.obj : error LNK2019: unresolved external symbol _MLInitializeIcon referenced in function _WinMain#16
1>D:\Applications\Mathematica\SystemFiles\Links\MathLink\DeveloperKit\Windows\MathLinkExamples\addtwo\Debug\addtwo.exe : fatal error LNK1120: 2 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I've followed all provided instructions from Wolfram's MathLink Developer Guide, and made sure to add "ml32i3m.lib" to Linker>Input>Additional Dependencies. Supposedly the ml32/ml64 lib files contain the information for MlMain. Any help is appreciated :)
I am performing a project with ITK for processing medical images. After a lot of work there is no further compilation errors, but in the linking process I am having the following info :
1>------Generation started: proyect: prueba_r01, configuration: Debug Win32 ------
1>Linking…
1>Creating library C:\Documents and Settings\GTTS\Mis documentos\Visual Studio 2008\Projects\prueba_r01\Debug\prueba_r01.lib and object C:\Documents and Settings\GTTS\Mis documentos\Visual Studio 2008\Projects\prueba_r01\Debug\prueba_r01.exp
1>prueba_r01.obj : error LNK2019: extern symbol "public: double (* __thiscall prueba_r01::multiply_matrix_2D(double ()[2],double ()[2],int,int))[2]" (?multiply_matrix_2D#prueba_r01##QAEPAY01NPAY01N0HH#Z) unresolved which is referenced in the function "private: void __thiscall prueba_r01::filtro(void)" (?filtro#prueba_r01##AAEXXZ)
1>C:\Documents and Settings\GTTS\Mis documentos\Visual Studio 2008\Projects\prueba_r01\Debug\prueba_r01.exe : fatal error LNK1120: 1 externos sin resolver
1>prueba_r01 - 2 errors, 0 warnings
========== Generar: 0 corrects, 1 incorrects, 0 actualized, 0 omited ==========
The method multiply_matrix_2D produces the error when is called inside the private slot “filtro()” (translated as filter)
The header of the file is :
#include <QtGui/QMainWindow>
#include "ui_prueba_r01.h"
#include "vicdef.h"
#include "itkImage.h"
#include "math.h"
#include <complex>
#include "fftw3.h"
using namespace std;
#define PI 3.14159265
class prueba_r01 : public QMainWindow
{
Q_OBJECT
public:
typedef double PixelType;
typedef itk::Image < PixelType, 2> ImageType;
ImageType::Pointer imagen;
double** H;
prueba_r01(QWidget *parent = 0, Qt::WFlags flags = 0);
~prueba_r01();
void matrix2D_H(int ancho, int alto, double eta, double sigma);
fftw_complex* multiply_matrix_2D(fftw_complex* out, fftw_complex* H,int a, int b);
private slots:
void openRGB();
void filtro();
private:
Ui::prueba_r01Class ui;
};
#endif // PRUEBA_R01_H
And the main part where the problem is located is in the .cpp file and is displayed here:
fftw_complex* res ;
res = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*a*b);
fftw_complex* H_casted= reinterpret_cast<fftw_complex*> (&H);
res = multiply_matrix_2D(out,H_casted, a, b);
The process of casting a **double pointer to *fftw_complex is done here, because I want to multiply a filter in frequency domain (H(w)) with the result of the fft transform of an image, that’s the reason. Is important to remark that fftw_complex is double[2], the first row for the real part, and the second for the imaginary
And the problematic method is shown below:
fftw_complex* multiply_matrix_2D(fftw_complex* out, fftw_complex* H, int a ,int b){
/* The matrix out[axb] or [n0x(n1/2)+1] is the image after the FFT , and the out_H[axb] is the filter in the frequency domain,
both are multiplied POINT TO POINT, it has to be called twice, one for the imaginary part and another for the normal part
*/
fftw_complex *res;
res = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*a*b);
for (int i0 = 0; i0<a ; i0++){
for (int i1 = 0; i1<b ; i1++){
res[i1+a*i0][0] = out[i1+a*i0][0]*(H[0][0]+H[0][1]); // real part
res[i1+a*i0][1] = out[i1+a*i0][1]*(H[0][0]+H[0][1]); // imaginary part
}
}
return res;
}
Any help will be really nice!! I’m quite lost now…
Thanks! Gracias!
Antonio
Change the function header in the cpp file to:
fftw_complex* prueba_r01::multiply_matrix_2D(fftw_complex* out, fftw_complex* H, int a, int b)
You forgot the class name (prueba_r01::) in the implementation, therefore it doesn't find the function body