Click here to Skip to main content
15,886,963 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm working on a project that involves integrating the Zoom SDK into my application. As part of this integration, I'm trying to implement a custom class named RawAudioDelegate to handle raw audio data. However, I'm encountering linker errors related to unresolved external symbols when trying to build my project.

Description:

I have a class named RawAudioDelegate which inherits from IZoomSDKAudioRawDataDelegate from the Zoom SDK. In my header file RawAudioDelegate.h, I have declared two methods: onOneWayAudioRawDataReceived and onMixedAudioRawDataReceived. The implementations for these methods are provided in a separate .cpp file named RawAudioDelegate.cpp.

The issue arises during the linking phase, where I get the following linker errors:
Error LNK2001: unresolved external symbol "public: virtual void __thiscall RawAudioDelegate::onOneWayAudioRawDataReceived(class AudioRawData *,unsigned int)" ...
Error LNK2001: unresolved external symbol "public: virtual void __thiscall RawAudioDelegate::onMixedAudioRawDataReceived(class AudioRawData *)" ...

My Code Snippets:
C++
cpp file
//added for raw data access
#include "stdafx.h"
#include "rawdata/rawdata_audio_helper_interface.h"
#include "RawAudioDelegate.h"
#include "zoom_sdk_def.h"

#include <fstream>

//added for raw data access
using namespace std;
using namespace ZOOM_SDK_NAMESPACE;

//added for raw data access
void RawAudioDelegate::onOneWayAudioRawDataReceived(AudioRawData* data_, uint32_t node_id)
{
	std::cout << "+++ data received from node:" << node_id << std::endl;
	//int buffer_len = data_->GetBufferLen();
	//std::cout << buffer_len;
}

//added for raw data access
void RawAudioDelegate::onMixedAudioRawDataReceived(AudioRawData* data_)
{
	std::cout << "Received onMixedAudioRawDataReceived" << std::endl;
	//int buffer_len = data_->GetBufferLen();
	//std::cout << buffer_len;

	static ofstream pcmFile;
	pcmFile.open("audio.pcm", ios::out | ios::binary | ios::app);

	if (!pcmFile.is_open()) {
		cout << "Failed to open wave file" << endl;
		return;
	}
	try {
		// Write the audio data to the file
		pcmFile.write((char*)data_->GetBuffer(), data_->GetBufferLen());
		//std::cout << "buffer length: " << audioRawData->GetBufferLen() << std::endl;
		std::cout << "buffer : " << data_->GetBuffer() << std::endl;

		// Close the wave file
		pcmFile.close();
		pcmFile.flush();
	}
	catch (exception e)
	{
		cout << "Failed to write wave file" << endl;
	}
}

Header file
C++
//added for raw data access
#pragma once
#include "stdafx.h"
#include "rawdata/rawdata_audio_helper_interface.h"
#include "zoom_sdk.h"
#include "zoom_sdk_raw_data_def.h"
#include <iostream>

//added for raw data access
using namespace std;
using namespace ZOOM_SDK_NAMESPACE;

class RawAudioDelegate :
	public ZOOM_SDK_NAMESPACE::IZoomSDKAudioRawDataDelegate
{
public:
	virtual void onMixedAudioRawDataReceived(AudioRawData* data_);
	virtual void onOneWayAudioRawDataReceived(AudioRawData* data_, uint32_t node_id);
};


What I have tried:

I have checked that the RawAudioDelegate.cpp file is included in the project.
I verified that the header guard in RawAudioDelegate.h is correctly defined.
I confirmed that I'm using the correct configuration (x86/x64) to match the SDK and project architecture.
I have checked that I'm correctly linking against the necessary Zoom SDK libraries.
Posted
Updated 14-Sep-23 9:25am
v7

Try the following changes in your header file:
C++
public:
    // make these virtual methods 
    virtual void onMixedAudioRawDataReceived(AudioRawData* data_);
    virtual void onOneWayAudioRawDataReceived(AudioRawData* data_, uint32_t node_id);
};
 
Share this answer
 
Comments
MANIKANTA R 2023 22-Aug-23 6:26am    
virtual methods already present in the header file
Richard MacCutchan 22-Aug-23 6:35am    
Well something is either not being compiled correctly or not being included in the link phase.
MANIKANTA R 2023 22-Aug-23 6:54am    
"Could you please review the code snippets I've included? Afterward, I would appreciate any suggestions you can provide for corrections. I have ensured that all the dependencies and libraries are properly included. I have also made modifications to the code to achieve my intended functionalities."

Richard MacCutchan 22-Aug-23 7:34am    
Without access to all the source code, and the build files it is almost impossible to make any further suggestions. The only other item that may be a clue, is that the code that is calling these two methods is using the __thiscall calling convention, and it may be that the generated code is using __cdecl; but that is just a guess. So find out which module(s) is making these calls and check if there are any options/pragmas etc. that may be changing the default calling conventions. Further details can be found at __thiscall | Microsoft Learn[^].
Check your makefile: if RawAudioDelegate.cpp isn't compiled in there, and the resulting object / library file included in the linker list it can't be found - which is what the error is telling you.
 
Share this answer
 
Well, starting at a point where I can help you find the reason for the LINK2001, add /VERBOSE to the linker COMMAND LINE; this will make the link attempt OUTPUT lengthy. What you want to see there is what exactly the LINKER is doing when it is doing it. I believe the LNK2001 error you're getting is the result of you the compiler/linker NOT providing a path or a name, for that matter, of a required .lib file.

When the LINKER goes looking for the function bodies (location) it's searching in all the named paths provided by the project assembler (bad choice of words that; the project configurator (even worse I guess)); YOU, the guy who knows everything about the modules he's written and put his INCLUDES, his SOURCES, and his RESOURCES in the thing VS sees as having all the PROPERTIES found under the "Project Property Pages". Sub-CONFIGURATION is LINKER. And Sub-LINKER is INPUT ... and if you go to that tab you'll see that there's "Additional Dependencies" etc. That's a WHERE that when the LINKER gets to it, through searching a known PATH, it's going to encounter the functions available to it.

Get it? When the LINKER goes searching for a function it can't find anywhere, in this case "RawAudioDelegate::onOneWayAudioRawDataReceived", it'll err because there's no .lib for it to access in order to find ... wait for it ... THAT STRING. Or, part of that string I should say. The linker does what is called "mangling" of a function body. Which in short means that some or most of the NAME of the function is getting changed, and for the sake of explanation, there are too many reasons why it does, so it just does this. But without more reason all you need to know is that YOU can search using what search facility is available to you on you're computer for the missing function body yourself by finding where all your LIB files are and allowing it to get the text of the beginning of the filename. For example "RawAudioDeleg" or "OneWayAudioRaw".

Looking through the LINKER OUTPUT after a LINK attempt with the VERBOSE switch (/V) on the command line and comparing it to the non-verbose output, you'll clearly see what's happening and what I'm talking about. Once you find the library that contains your function body, you add it to the resources path as an "ADDITIONAL" resource.

If the function body can't be found then the LIBRARY is not on your computer and you'll have to contact the coder of your project and ask him why he hasn't included the .lib file or provided the code to make one yourself.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900