LNK2019 त्रुटि को हल करने के लिए कैसे: अनसुलझे बाहरी प्रतीक - फ़ंक्शन?


99

मुझे यह त्रुटि मिली, लेकिन मुझे नहीं पता कि इसे कैसे ठीक किया जाए।

मैं Visual Studio 2013 का उपयोग कर रहा हूं। मैंने समाधान का नाम MyProjectTest बनाया है यह मेरे परीक्षण समाधान की संरचना है:

संरचना

- समारोह

#ifndef MY_FUNCTION_H
#define MY_FUNCTION_H

int multiple(int x, int y);
#endif

-function.cpp

#include "function.h"

int multiple(int x, int y){
    return x*y;
}

- main.cpp

#include <iostream>
#include <cstdlib>
#include "function.h"
using namespace std;

int main(){
    int a, b;
    cin >> a >> b;
    cout << multiple(a, b) << endl;

    system("pause");
    return 0;
}

मैं एक नौसिखिया हूं; यह एक सरल कार्यक्रम है और यह बिना किसी त्रुटि के चलता है। मैंने इंटरनेट में पढ़ा और यूनिट टेस्ट में दिलचस्पी पैदा की, इसलिए मैंने एक टेस्ट प्रोजेक्ट बनाया:

फ़ाइल> नया> प्रोजेक्ट ...> इंस्टॉल किया गया> टेम्पलेट> विज़ुअल सी ++> टेस्ट> नेटिव यूनिट टेस्ट प्रोजेक्ट>

नाम: UnitTest1 समाधान: समाधान में जोड़ें तब स्थान वर्तमान खुले समाधान के पथ पर स्वतः-स्विच हो जाता है। यह समाधान की फ़ोल्डर संरचना है:

फ़ोल्डर संरचना

मैंने केवल फ़ाइल unittest1.cpp को संपादित किया है:

#include "stdafx.h"
#include "CppUnitTest.h"
#include "../MyProjectTest/function.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace UnitTest1
{       
    TEST_CLASS(UnitTest1)
    {
    public:

        TEST_METHOD(TestEqual)
        {

            Assert::AreEqual(multiple(2, 3), 6);
            // TODO: Your test code here
        }

    };
}

लेकिन मुझे त्रुटि LNK2019 मिलती है: अनसुलझे बाहरी प्रतीक। मुझे पता है कि फ़ंक्शन मल्टीपल का कार्यान्वयन गायब है। मैंने function.cpp फ़ाइल को हटाने की कोशिश की और मैंने घोषणा को परिभाषा के साथ बदल दिया, और यह चलता है। लेकिन एक ही फ़ाइल में घोषणा और परिभाषा दोनों लिखने की सिफारिश नहीं की जाती है। मैं इस त्रुटि को बिना किए कैसे ठीक कर सकता हूं? क्या मुझे #include "../MyProjectTest/function.cpp"फ़ाइल unittest.cpp से बदलना चाहिए ? (मैं अंग्रेजी में बहुत अच्छा नहीं हूं। धन्यवाद)



6
BE CAREFUL एक विंडोज़ वातावरण में, स्थिर पुस्तकालयों में एक .LIBफाइल एक्सटेंशन होता है। चीजों को जटिल करने के लिए ... डायनेमिक लिंक लाइब्रेरी (यानी *.DLL) में एक साथ आयात लाइब्रेरी हो सकती है जिसमें .LIBफ़ाइल एक्सटेंशन भी होता है । इस आयात पुस्तकालय में दी गई सभी अच्छाइयों को सूचीबद्ध किया गया है *.DLL। अधिक जानकारी के लिए, कृपया पढ़ें: बिगिनर्स गाइड टू
लिंकर्स

4
वह सावधान क्यों होना चाहिए ??
मार्शल शिल्प

जवाबों:


80

एक विकल्प function.cppआपकी UnitTest1परियोजना में शामिल होगा , लेकिन यह सबसे आदर्श समाधान संरचना नहीं हो सकता है। आपकी समस्या का संक्षिप्त उत्तर यह है कि आपकी UnitTest1परियोजना का निर्माण करते समय , संकलक और लिंकर का कोई विचार नहीं है जो function.cppमौजूद है, और यह भी लिंक करने के लिए कुछ भी नहीं है जिसमें परिभाषा है multiple। इसे ठीक करने का एक तरीका पुस्तकालयों को जोड़ने का उपयोग करना है।

चूंकि आपकी इकाई परीक्षण एक अलग परियोजना में हैं, इसलिए मुझे लगता है कि आपका इरादा उस परियोजना को एक स्टैंडअलोन इकाई-परीक्षण कार्यक्रम बनाना है। जिन फ़ंक्शन के साथ आप किसी अन्य प्रोजेक्ट में स्थित परीक्षण कर रहे हैं, उन प्रोजेक्ट को या तो डायनामिक या स्टेटिक रूप से लिंक किए गए लायब्रेरी में बनाना संभव है। स्टैटिक लाइब्रेरी बिल्ड टाइम में अन्य प्रोग्राम्स से जुड़ी होती हैं .lib, और इनका एक्सटेंशन होता है , और डायनेमिक लाइब्रेरी रनटाइम पर लिंक होती हैं, और इनका एक्सटेंशन होता है .dll। मेरे जवाब के लिए मैं स्टेटिक लाइब्रेरी पसंद करूंगा।

आप अपने पहले प्रोग्राम को प्रोजेक्ट प्रॉपर्टीज में बदलकर स्टैटिक लाइब्रेरी में बदल सकते हैं। सामान्य टैब के तहत एक विकल्प होना चाहिए जहां परियोजना एक निष्पादन योग्य ( .exe) के निर्माण के लिए निर्धारित है । आप इसे बदल सकते हैं .lib.libफ़ाइल के रूप में एक ही जगह पर निर्माण करेगा .exe

अपनी UnitTest1परियोजना में, आप इसके गुणों पर जा सकते हैं, और श्रेणी अतिरिक्त लाइब्रेरी निर्देशिकाएँ में लिंकर टैब के तहत, जो पथ MyProjectTestबनाता है उसे जोड़ सकते हैं । फिर, लिंकर - इनपुट टैब के तहत अतिरिक्त निर्भरता के लिए, अपने स्थिर पुस्तकालय का नाम जोड़ें, सबसे अधिक संभावना है MyProjectTest.lib

जो आपके प्रोजेक्ट को बनाने की अनुमति दे। ध्यान दें कि ऐसा करने से, MyProjectTestएक स्टैंडअलोन निष्पादन योग्य कार्यक्रम नहीं होगा जब तक कि आप इसके निर्माण गुणों को आवश्यकतानुसार नहीं बदलते हैं, जो आदर्श से कम होगा।


'लिंकर-> इनपुट टैब' में, मुझे स्टैटिक लाइब्रेरी के लिए उपसर्ग '(आउटडिअर)' करना पड़ा, जो कि '$ (आउटडिअर) मायप्रोजेक्टेस्ट.लिब' है, हालांकि 'रूट' में 'MyProject' और 'MyTestProject' दोनों का स्थान एक ही रूट फ़ोल्डर में रखा गया है। ।
पाबित्रा डैश

13
इसलिए हर बार जब आप यूनिट टेस्ट चलाना चाहते हैं तो आपको अपने टेस्टी प्रोजेक्ट को स्टैटिक लाइब्रेरी में बदलना चाहिए, और हर बार जब आप वास्तव में अपना प्रोग्राम चलाना चाहते हैं तो आप इसे एक एक्जीक्यूटेबल में बदल सकते हैं, यह कैसा समाधान है?
ए। धुआलीक

1
यदि MyProjectTest एक dll है, तो क्या हम इसका परीक्षण कर सकते हैं? हम सिर्फ आयात लिब को जोड़ते हैं या हमें obj फाइल को जोड़ना चाहिए?
19

"आप अपने पहले प्रोग्राम को प्रोजेक्ट प्रॉपर्टीज में बदलकर स्टैटिक लाइब्रेरी में बदल सकते हैं। जनरल टैब के तहत एक ऑप्शन होना चाहिए, जहां प्रोजेक्ट एक्जीक्यूटेबल (.exe) बनाने के लिए सेट हो। आप इसे .lib में बदल सकते हैं। .Lib फ़ाइल .exe के रूप में एक ही स्थान पर बनाएगी "ऐसा करना मेरे मामले के लिए पर्याप्त था। बाकी को पहले ही वी.एस.
एक्रेम सोलमाज़

39

Visual Studio समाधान ट्री में प्रोजेक्ट 'UnitTest1' पर राइट क्लिक करें - फिर जोड़ें -> मौजूदा आइटम -> फ़ाइल चुनें ../MyProjectTest/function.cpp


4
ध्यान दें कि वास्तविक फ़ाइल (ओं) को कॉपी नहीं किया गया है या प्रोजियर में स्थानांतरित नहीं किया गया है।
लॉरी स्टर्न

सीएलआई परियोजना के लिए सी + + काम जोड़ने के लिए इसी तरह की समस्याओं को हल करने के लिए इस तरह की समस्या का हल हुआ।
देशन मरा

17

चूंकि मैं चाहता हूं कि मेरी परियोजना एक स्टैंडअलोन EXE के लिए संकलित हो, मैंने UnitTest प्रोजेक्ट को function.obj फ़ाइल से लिंक किया। function.cpp से उत्पन्न फ़ाइल और यह काम करता है। 'UnitTest1' प्रोजेक्ट> कॉन्फ़िगरेशन गुण> लिंकर> इनपुट> अतिरिक्त निर्भरता> "" .. \ MyProjectTest \ Debug \ function.obj पर राइट क्लिक करें।


1
कैसे के बारे में जब MyProjectTest एक dll है? क्या आप इसके लिए सेटिंग कर सकते हैं?
11

अगर हमारे पास कई obj फाइल है। क्या हम इस तरह की कुछ चीज़ों को जोड़ सकते हैं * .obj? आपके समाधान ने मेरे साथ काम किया लेकिन मैं हर नई obj फ़ाइलों को मैन्युअल रूप से जोड़ना नहीं चाहता।
19

10

मैं सिर्फ विजुअल स्टूडियो 2013 में इस समस्या में भाग गया। जाहिर है, एक ही समाधान में दो परियोजनाएं होना और निर्भरता स्थापित करना पर्याप्त नहीं है। आपको उनके बीच एक परियोजना संदर्भ जोड़ना होगा। ऐसा करने के लिए:

  1. समाधान का पता लगाने में परियोजना पर राइट-क्लिक करें
  2. Add => References पर क्लिक करें ...
  3. नया संदर्भ जोड़ें बटन पर क्लिक करें
  4. उन प्रोजेक्ट के लिए बॉक्स चेक करें, जिन पर यह प्रोजेक्ट निर्भर करता है
  5. ओके पर क्लिक करें

निर्भरता स्थापित करने से आपका क्या मतलब है? मैंने संदर्भ जोड़ा लेकिन इसकी अभी भी शिकायत थी। devblogs.microsoft.com/cppblog/cpp-testing-in-visual-studio ने सुझाव दिया कि पर्याप्त होगा।
tschumann

8

यह पता चला कि मैं .cpp फ़ाइलों के साथ .c फ़ाइलों का उपयोग कर रहा था। नाम बदलकर .c .cpp ने मेरी समस्या हल कर दी।


6

एक और तरीका है कि आप इस लिंकर त्रुटि को प्राप्त कर सकते हैं (जैसा कि मैं था) यदि आप एक dll से एक वर्ग का एक उदाहरण निर्यात कर रहे हैं, लेकिन उस वर्ग को आयात / निर्यात के रूप में घोषित नहीं किया है।

 #ifdef  MYDLL_EXPORTS 
    #define DLLEXPORT __declspec(dllexport)  
 #else
    #define DLLEXPORT __declspec(dllimport)  
 #endif

class DLLEXPORT Book // <--- this class must also be declared as export/import
{
public: 
    Book();
    ~Book();
    int WordCount();
};

DLLEXPORT extern Book book; // <-- This is what I really wanted, to export book object

इसलिए भले ही मुख्य रूप से मैं ऊपर कहे गए पुस्तक वर्ग का सिर्फ एक उदाहरण निर्यात कर bookरहा था, मुझे Bookकक्षा को निर्यात / आयात वर्ग के रूप में घोषित करना था अन्यथा book.WordCount()अन्य डीएल में कॉल करना एक लिंक त्रुटि पैदा कर रहा था।


2

यह मेरे साथ हुआ था इसलिए मुझे लगा कि मैं अपना समाधान साझा कर सकता हूं, जितना आसान था:

कॉन्फ़िगरेशन गुण -> सामान्य -> चरित्र सेट में दोनों परियोजनाओं के वर्ण सेट की जाँच करें

मेरी यूनिटटेस्ट परियोजना डिफॉल्ट कैरेक्टर सेट मल्टी-बाइट का उपयोग कर रही थी, जबकि मेरे काम यूनिकोड में
मेरा फ़ंक्शन पैरामीटर के रूप में एक TCHAR का उपयोग कर रहा था । मेरे दायित्व के परिणामस्वरूप मेरा TCHAR एक WCHAR में बदल गया था, लेकिन यह मेरे UnitTest पर एक चार * था : प्रतीक अलग थे क्योंकि पैरामीटर वास्तव में अंत में समान नहीं थे।


1

मुझे बस यही पता चला LNK2019 विजुअल स्टूडियो 2015 में संकलन के दौरान होता है अगर किसी वर्ग के अंदर घोषित फ़ंक्शन के लिए परिभाषा प्रदान करना भूल जाता है।

लिंकर त्रुटि अत्यधिक गुप्त थी, लेकिन मैंने नीचे पढ़ा था कि त्रुटि के माध्यम से पढ़ने से क्या गायब था और कक्षा के बाहर की परिभाषा को स्पष्ट करने के लिए प्रदान किया।


कुछ मामलों में मुद्दा यह है कि वर्ग दोष वाले शीर्षकों को सभी अच्छी तरह से संदर्भित / शामिल किया गया है, लेकिन उनके संबंधित cpps लिंकर को उपलब्ध नहीं किए जा सकते हैं । समाधान एक्सप्लोरर में प्रोजेक्ट बाहरी निर्भरता के माध्यम से जांच करने का सबसे अच्छा तरीका है। हालांकि वीएस के लिए यह फायदेमंद होगा कि वह किसी तरह की फाइल के अस्तित्व / त्रुटि के संबंध में चेतावनी जारी करें।
लॉरी स्टर्न

1

मेरे मामले में, संपत्ति में "C / C ++ कंपाइलर" के लिए cpp फ़ाइल सेट करें -> LNK2019 त्रुटि को हल करें।


0

मेरे लिए काम करता है, अगर मैं इस लाइन .vcxprojको itemGroupbpp फ़ाइल में जोड़ता हूं , जो हेडर फ़ाइल से जुड़ा है।

<ClCompile Include="file.cpp" />

0

विजुअल स्टूडियो 2017 में यदि आप सार्वजनिक सदस्यों का परीक्षण करना चाहते हैं, तो बस अपनी वास्तविक परियोजना और परीक्षण परियोजना को एक ही समाधान में डालें, और परीक्षण परियोजना में अपनी वास्तविक परियोजना के लिए एक संदर्भ जोड़ें।

देखें दृश्य स्टूडियो में सी ++ यूनिट टेस्टिंग से MSDN अधिक जानकारी के लिए ब्लॉग। आप विजुअल स्टूडियो में C / C ++ के लिए यूनिट टेस्ट भी लिख सकते हैं और साथ ही विजुअल स्टूडियो में C ++ के लिए Microsoft यूनिट टेस्टिंग फ्रेमवर्क का उपयोग कर सकते हैं , बाद वाला यदि आपको गैर-सार्वजनिक सदस्यों का परीक्षण करने और उसी प्रोजेक्ट में परीक्षण करने की आवश्यकता है अपने असली कोड के रूप में।

ध्यान दें कि जिन चीजों का आप परीक्षण करना चाहते हैं, उनका उपयोग करके निर्यात करना होगा __declspec(dllexport)। अधिक विवरण के लिए __declspec (dllexport) का उपयोग कर DLL से निर्यात देखें ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.