2014-11-18 2 views
0

У меня есть два приложения Winusb и копирование данных с процессора на GPU с использованием CUDA. Оба работают отлично, как два отдельных проекта, но когда я пытаюсь объединить их как один проект, я получаю следующую ошибку связывания.Ошибка компоновщика 2019 при связывании приложения Winusb и CUDA

бревенчатых:

1>------ Build started: Project: USB Application2, Configuration: Win7 Debug Win32 ------ 
1> Compiling CUDA source file function.cu... 
1> 
1> C:\Users\bel1\documents\visual studio 2012\Projects\USB Application2\USB Application2>"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\bin\nvcc.exe" -gencode=arch=compute_10,code=sm_10 --use-local-env --cl-version 2010 -ccbin "C:\Program Files\Microsoft Visual Studio 11.0\VC\bin" -IWin7Debug\ -IWin7Debug\ -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include"  --keep-dir Win7Debug -maxrregcount=0 --machine 32 -cuda -cudart static  -D_X86_=1 -Di386=1 -DSTD_CALL -DWIN32_LEAN_AND_MEAN=1 -D_WIN32_WINNT=0x0601 -DWINVER=0x0601 -DWINNT=1 -DNTDDI_VERSION=0x06010000 -DDBG=1 -D_AFXDLL -Xcompiler "/EHsc /W0 /nologo /Od /Zi /RTC1 /MT " -o Win7Debug\function.cu.obj "C:\Users\bel1\documents\visual studio 2012\Projects\USB Application2\USB Application2\function.cu" 
1> Compiling CUDA source file wrapper.cu... 
1> 
1> C:\Users\bel1\documents\visual studio 2012\Projects\USB Application2\USB Application2>"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\bin\nvcc.exe" -gencode=arch=compute_10,code=sm_10 --use-local-env --cl-version 2010 -ccbin "C:\Program Files\Microsoft Visual Studio 11.0\VC\bin" -IWin7Debug\ -IWin7Debug\ -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include"  --keep-dir Win7Debug -maxrregcount=0 --machine 32 -cuda -cudart static  -D_X86_=1 -Di386=1 -DSTD_CALL -DWIN32_LEAN_AND_MEAN=1 -D_WIN32_WINNT=0x0601 -DWINVER=0x0601 -DWINNT=1 -DNTDDI_VERSION=0x06010000 -DDBG=1 -D_AFXDLL -Xcompiler "/EHsc /W0 /nologo /Od /Zi /RTC1 /MT " -o Win7Debug\wrapper.cu.obj "C:\Users\bel1\documents\visual studio 2012\Projects\USB Application2\USB Application2\wrapper.cu" 
1>main.obj : error LNK2019: unresolved external symbol "short * __stdcall speccud(short * const)" ([email protected]@[email protected]) referenced in function _main 
1>C:\Users\bel1\documents\visual studio 2012\Projects\USB  Application2\Win7Debug\USBApplication2.exe : fatal error LNK1120: 1 unresolved externals 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 

main.cpp

#include "pch.h" 
short *speccud(short ispecbu[]); 

LONG __cdecl _tmain(LONG Argc, LPTSTR ** Argv) 
//int main(int argc, char **argv) 
{ 
FILE *output_file1 = fopen("output_file2.txt", "w"); 
FILE *output_file2 = fopen("output_file3.txt", "w"); 
DEVICE_DATA   deviceData; 
HRESULT    hr; 
USB_DEVICE_DESCRIPTOR deviceDesc; 
BOOL     bResult; 
BOOL     noDevice; 
ULONG     lengthReceived; 
BOOL wrResult = TRUE; 
BOOL wr1Result = TRUE; 
BOOL RQResult = 0; 
UNREFERENCED_PARAMETER(Argc); 
UNREFERENCED_PARAMETER(Argv); 


//////////////////////Open device /////////////// 
hr = OpenDevice(&deviceData, &noDevice); 
if (FAILED(hr)) { 
    if (noDevice) { 
     printf(_T("Device not connected or driver not installed\n")); 
    } else { 
     printf(_T("Failed looking for device, HRESULT 0x%x\n"), hr); 
    } 
    std::getchar(); 
    return 0; 
} 

/////////////////////Get descriptor////////////////// 
bResult = WinUsb_GetDescriptor(deviceData.WinusbHandle, 
           USB_DEVICE_DESCRIPTOR_TYPE, 
           0, 
           0, 
           (PBYTE) &deviceDesc, 
           sizeof(deviceDesc), 
           &lengthReceived); 
    if (FALSE == bResult || lengthReceived != sizeof(deviceDesc)) { 

    printf(_T("Error among LastError %d or lengthReceived %d\n"), 
      FALSE == bResult ? GetLastError() : 0, 
      lengthReceived); 
    CloseDevice(&deviceData); 
    return 0; 
} 

bool sResult = FALSE;bool syResult; 
bool sResult1 = FALSE;bool syResult1; 
//Initialize 
UCHAR Intialize[] = {0x01}; 
ULONG cbISize = strlen((char*)Intialize); 
ULONG InSent = 0; 
wrResult = WinUsb_WritePipe(deviceData.WinusbHandle, 0x01, Intialize, 1, &InSent, 0); 
//Integration time - 700ms 
UCHAR Inttime[] = {0x0200100000}; 
ULONG cbITSize = strlen((char*)Inttime); 
ULONG InttimeSent = 0; 
wrResult = WinUsb_WritePipe(deviceData.WinusbHandle, 0x01, Inttime, 5, &InttimeSent, 0); 
//strobe signal 
UCHAR strobe1[] = {0x030001}; 
ULONG strobeSize1 = strlen((char*)strobe1); 
ULONG strobeSent1 = 0; 
wr1Result = WinUsb_WritePipe(deviceData.WinusbHandle, 0x01, strobe1, 3, &strobeSent1, 0); 
//Request spectra 
UCHAR Rqspectra[] = {0x09}; 
ULONG RqSize = strlen((char*)Rqspectra); 
ULONG RqSent = 0; 
RQResult = WinUsb_WritePipe(deviceData.WinusbHandle, 0x01, Rqspectra,1, &RqSent, 0); 
//Pixel Values 
UCHAR szBuffer[15][512]; 
UCHAR sz1Buffer[1]; 
UCHAR tBuffer[1]; 
ULONG tReadx; 
ULONG cbReadx[16]; 
USHORT newbuf[15][512]; 
short specbu[7860]; 
short *fans; 
for (int i=0;i<16;i++) 
{ 
    if (i<4) 
    { 
     sResult = WinUsb_ReadPipe(deviceData.WinusbHandle, 0x86, szBuffer[i], 512, &cbReadx[i], 0); 
    } 
    else if (i>=4 && i<15) 
    { 
     sResult = WinUsb_ReadPipe(deviceData.WinusbHandle, 0x82, szBuffer[i], 512, &cbReadx[i], 0); 
    } 
    else if (i = 15) 
    { 
     syResult = WinUsb_ReadPipe(deviceData.WinusbHandle, 0x82, sz1Buffer, 1, &cbReadx[i], 0); 
    } 

} 
int pon=0; 
for (int k=0;k<15;k++) 
{ 
for (int l=0;l<512;l+=2) 
{ 
    newbuf[k][l] = (szBuffer[k][(l+1)]<<8|szBuffer[k][l]); 
    specbu[pon]= (szBuffer[k][(l+1)]<<8|szBuffer[k][l]); 
    fprintf(output_file1,"%d\t\n",specbu[pon]); 
    pon++; 

} 
} 
//printf("%d",sizeof(specbu)); 
//short ARR[5] = {1,2,3,4,5}; 
//fans=speccud(ARR); 
fans = speccud(specbu); 
for (int k=0;k<5;k++) 
{printf("%d", fans[k]); 
    //fprintf(output_file2,"%d\t\n",fans[k]); 
    //tempc[k]=specbu[k]; 
} 
std::getchar(); 
CloseDevice(&deviceData); 
return 0; 
} 

Wrapper.cu

#include "cuda_runtime.h" 
#include <cuda.h> 
#include <cstdio> 
#include "device_launch_parameters.h" 


__global__ void saxpy(int cn, short ca, short *cx, short *cy); 
short *speccud(short ispecbu[]) 
{ 
    const int cN = 7680; 
    short *cx, *cd_x, *cd_y; 
    static short *cy; 
    cx = (short*)malloc(cN*sizeof(short)); 
    cy = (short*)malloc(cN*sizeof(short)); 
    cudaMalloc(&cd_x, cN*sizeof(short)); 
    cudaMalloc(&cd_y, cN*sizeof(short)); 
for (int ci = 0; ci < cN; ci++) { 
    cx[ci] = ispecbu[ci]; 
    //y[i] = 2.0f; 
    } 
cudaMemcpy(cd_x, cx, cN*sizeof(short), cudaMemcpyHostToDevice); 
cudaMemcpy(cd_y, cy, cN*sizeof(short), cudaMemcpyHostToDevice); 
// Perform SAXPY on 1M elements 
saxpy<<<(cN+255)/256, 256>>>(cN, 1, cd_x, cd_y); 
cudaMemcpy(cy, cd_y, cN*sizeof(short), cudaMemcpyDeviceToHost); 
return cy; 
} 

Function.cu

#ifndef __Kernel_CU__ 
#define __Kernel_CU__ 
__global__ void saxpy(int cn, short ca, short *cx, short *cy) 
{ 
int ci = blockIdx.x*blockDim.x + threadIdx.x; 
    cy[ci] = ca+cx[ci]; 
} 

#endif 

У меня также есть device.cpp, который имеет функцию opendevice, closedevice и т. Д. (Часть Winusb и слишком много строк автоматически сгенерированного кода). Это похоже на некоторую ошибку компоновщика между приложением Cuda и Winusb. когда я просто создаю два визуальных проекта студии один для Cuda, а другой для winusb оба отлично работают.

+0

Проблема в том, что компоновщик не может найти функцию 'speccud'. Вы уверены, что ваш проект настроен для компиляции и сборки ваших файлов CU? Я бы предположил, что нет, так как там реализуется реализация этой функции. – Preston

+0

@Preston Я обновил журнал сборки. Вы можете видеть, что это говорит о компиляции functions.cu и wrapper.cu. Я даже удалил предыдущие файлы .cu и создал его снова и связал, все равно заканчивается той же ошибкой. Я что-то упускаю? – Cedric

+0

Возможно ли, что имена искалечены в ваших файлах CU? Попробуйте добавить следующее к объявлению функции: 'extern 'C" short * speccud (short ispecbu []) ' – Preston

ответ

0

Компонент рассматривает символы, которые требуются main.cpp (т. Е. Точки входа, необходимые для main.obj), и пытается найти определения для этих точек входа в других модулях вашего проекта.

В случае main.obj, был один символ (точка входа), что не может найти определенные в другом месте:

1>main.obj : error LNK2019: unresolved external symbol "short * __stdcall speccud(short * const)" ([email protected]@[email protected]) referenced in function _main 

В этом случае, компоновщик говорит "Я ищу для функция определяется следующим образом:

short * __stdcall speccud(short * const) 

, но я не могу найти его!».

Конечно, вы не украсили свой прототип в main.cpp с помощью __stdcall, что было сделано автоматически компилятором, прежде чем он решил, какой символ нужен извне. Компилятор VS C++ может вести себя самыми разными способами, и в этом случае его поведение при компиляции файла main.cpp отличается от его (украшающего) поведения при компиляции Wrapper.cu. В результате функция speccud в Wrapper.cu экспортировалась под другим именем, чем то, что было определено по умолчанию main.obj, поэтому компоновщик не смог их сопоставить.

Таким образом, если вы избегаете этого путаницы, вызывая функцию в Wrapper.cu, чтобы получить экспорт таким образом, который точно соответствует тому, что говорит компоновщик в main.obj, тогда компоновщик может найти совпадение:

компоновщик сказал, "Я ищу:"

short * __stdcall speccud(short * const) 

так, если вы измените прототип:

short * __stdcall speccud(short * const); 

и определение функции:

short * __stdcall speccud(short * const ispecbu) 

тогда все соответствует.

(в C++ связи, сам процесс согласования основан на искаженной имя, которое так:

[email protected]@[email protected] 

но процесс сообщения об ошибках также demangles, что для нас:

short * __stdcall speccud(short * const) 

mangling/demangling следует определенной процедуре, поэтому вы можете использовать an online demangling service, чтобы преобразовать измененное имя в его дизассемблированную версию. Измененная версия этой функции выглядела бы иначе, если бы функция не имела __stdcall decoration.)

+0

Когда я использовал «extern» C «" Я закончил с 'main.obj: ошибка LNK2019: нерешенный внешний символ _speccud @ 4, на который ссылается функция _main.' Здесь у меня нет искаженного имени'? Speccud @@ YGPAFQAF @ Z', что должен делать кто-то в этом случае? (Нет никакого понятия об искаженном имени). – Cedric

+0

Почему бы не задать новый вопрос? Я не знаю, где вы положили 'extern 'C" 'точно, и было бы неплохо увидеть полный и точный вывод компилятора. Давайте не будем пытаться покрыть все это в пространстве комментариев. Кроме того, кто-то может знать ответ, и новый вопрос станет лучше видимым. –

Смежные вопросы