2
votes

I'm trying to code a simple base64 encoder/decoder (to test my programming skill).

I can compile it, but it doesn't link, I've this message error:

C:\Documents and Settings\Facon\Escritorio>g++ base64.o main.o -o prueba.exe

main.o:main.cpp:(.text+0x24a): undefined reference to `Base64Encode(std::vector > const&)'

collect2: ld returned 1 exit status

Compiler & Linker: Mingw32 3.4.5 SO: Windows XP

This is my source code:

base64.h:

#ifndef BASE64_H
#define BASE64_H

#include <iostream>
#include <vector>

typedef unsigned char byte;

std::string Base64Encode(const std::vector<byte> &array);
std::vector<byte> Base64Decode(const std::string &array);

#endif

base64.cpp:

#include "base64.h"

std::string Base64Encode(std::vector<byte> &array)
{
 const char *base64_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 const unsigned int size = array.size();
 std::string output;

 for (unsigned int i = 0; (i < size); i++)
 {
  if ((size - i) > 3)
  { 
   output.push_back(static_cast<char>(base64_table[array[i] >> 2]));
   output.push_back(static_cast<char>(base64_table[((array[i++] & 0x03) << 4) | ((array[i] & 0xF0) >> 4)]));
   output.push_back(static_cast<char>(base64_table[((array[i++] & 0x0F) << 2) | ((array[i] & 0xC0) >> 4)]));
   output.push_back(static_cast<char>(base64_table[array[i] & 0x3F]));
  }
  else if ((size - i) == 3)
  {
   output.push_back(static_cast<char>(base64_table[array[i] >> 2]));
   output.push_back(static_cast<char>(base64_table[((array[i++] & 0x03) << 4) | ((array[i] & 0xF0) >> 4)]));
   output.push_back(static_cast<char>(base64_table[(array[i] & 0x0F) << 2]));
   output.push_back(static_cast<char>('='));
  }
  else if ((size - i) == 2)
  {
   output.push_back(static_cast<char>(base64_table[array[i] >> 2]));
   output.push_back(static_cast<char>(base64_table[(array[i] & 0x03) << 4]));
   output.push_back('=');
   output.push_back('=');
  }
 }

 return output;
}

std::vector<byte> Base64Decode(const std::string &array) // TODO
{
 const char *base64_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
}

main.cpp:

#include <iostream>
#include <vector>
#include "base64.h"

using namespace std;

int main(int argc, char *argv[])
{
 const char* prueba = "sure.";
 vector<byte> texto;
 string codificado;

 for (unsigned int i = 0; (prueba[i] != 0); i++)
 {
  texto.push_back(prueba[i]);
 }

 codificado = Base64Encode(texto);

 cout << codificado;

 return 0;
}

PD: Sorry for my bad knowledge of English :P

3
Check your posted code snippets, you should have gotten a compile error, not a link error.Hans Passant

3 Answers

4
votes

You're missing a const in the implementation of Base64Encode, it's declared as:

std::string Base64Encode(const std::vector<byte> &array);

But implemented as

std::string Base64Encode(std::vector<byte> &array) { ... }

The compiler thinks that you've overloaded the function (for const and non-const vectors) and thinks the implementation of the const version is missing.

2
votes

Your header declares Base64Encode to accept the type const std::vector<byte> &array while your source file declares it to accept the type std::vector<byte> &array -- notice the missing const qualifier.

So while base64.cpp compiles correctly, it doesn't get linked to the declaration in the header, which is the only prototype that main.cpp is aware of. When the linker runs, main is looking for the signature with the const qualifier, but it's nowhere to be found.

1
votes

The argument to Base64Encode is declared as const in the header but non-const in the .cpp file.