Namespaces in DLLs?

I have the following files: (in the form of a dll project)

dll.h
1
2
3
4
5
6
#ifndef _DLL_H_
#define _DLL_H_
/* Begin User-Defined */
#define export extern "C" __declspec (dllexport)
/* End User Defined   */ 
#endif /* _DLL_H_ */ 


dllmain.cpp:
1
2
3
4
5
6
7
8
#include "dll.h"
#include <windows.h>
#include "base64.h"

export char* base64_decode(char* str)
{
       return (char*)Base64::decode(str);
}


base64.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//  //
// ####   ###     ##                -= Base64 library =-                 //
// #   # #       # # Base64.h - Base64 encoder/decoder                   //
// ####  ####   #  #                                                     //
// #   # #   # ##### Encodes and decodes base64 strings                  //
// #   # #   #     # Ideas taken from work done by Bob Withers           //
// ####   ###      # R1                      2002-05-07 by Markus Ewald  //
//  //
#ifndef B64_BASE64_H
#define B64_BASE64_H

#include <string>

namespace Base64 {

  /// Encode string to base64
  inline std::string encode(const std::string &sString);
  /// Encode base64 into string
  inline std::string decode(const std::string &sString);

}; // namespace Base64

// ####################################################################### //
// # Base64::encode()                                                    # //
// ####################################################################### //
/** Encodes the specified string to base64

    @param  sString  String to encode
    @return Base64 encoded string
*/
inline std::string Base64::encode(const std::string &sString) {
  static const std::string sBase64Table(
  // 0000000000111111111122222222223333333333444444444455555555556666
  // 0123456789012345678901234567890123456789012345678901234567890123
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
  );
  static const char cFillChar = '=';
  std::string::size_type   nLength = sString.length();
  std::string              sResult;

  // Allocate memory for the converted string
  sResult.reserve(nLength * 8 / 6 + 1);

  for(std::string::size_type nPos = 0; nPos < nLength; nPos++) {
    char cCode;
  
    // Encode the first 6 bits
    cCode = (sString[nPos] >> 2) & 0x3f;
    sResult.append(1, sBase64Table[cCode]);

    // Encode the remaining 2 bits with the next 4 bits (if present)
    cCode = (sString[nPos] << 4) & 0x3f;
    if(++nPos < nLength)
      cCode |= (sString[nPos] >> 4) & 0x0f;
    sResult.append(1, sBase64Table[cCode]);

    if(nPos < nLength) {
      cCode = (sString[nPos] << 2) & 0x3f;
      if(++nPos < nLength)
        cCode |= (sString[nPos] >> 6) & 0x03;

      sResult.append(1, sBase64Table[cCode]);
    } else {
      ++nPos;
      sResult.append(1, cFillChar);
    }

    if(nPos < nLength) {
      cCode = sString[nPos] & 0x3f;
      sResult.append(1, sBase64Table[cCode]);
    } else {
      sResult.append(1, cFillChar);
    }
  }

  return sResult;
}

// ####################################################################### //
// # Base64::decode()                                                    # //
// ####################################################################### //
/** Decodes the specified base64 string

    @param  sString  Base64 string to decode
    @return Decoded string
*/
inline std::string Base64::decode(const std::string &sString) {
  static const std::string::size_type np = std::string::npos;
  static const std::string::size_type DecodeTable[] = {
  // 0   1   2   3   4   5   6   7   8   9 
    np, np, np, np, np, np, np, np, np, np,  //   0 -   9
    np, np, np, np, np, np, np, np, np, np,  //  10 -  19
    np, np, np, np, np, np, np, np, np, np,  //  20 -  29
    np, np, np, np, np, np, np, np, np, np,  //  30 -  39
    np, np, np, 62, np, np, np, 63, 52, 53,  //  40 -  49
    54, 55, 56, 57, 58, 59, 60, 61, np, np,  //  50 -  59
    np, np, np, np, np,  0,  1,  2,  3,  4,  //  60 -  69
     5,  6,  7,  8,  9, 10, 11, 12, 13, 14,  //  70 -  79
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24,  //  80 -  89
    25, np, np, np, np, np, np, 26, 27, 28,  //  90 -  99
    29, 30, 31, 32, 33, 34, 35, 36, 37, 38,  // 100 - 109
    39, 40, 41, 42, 43, 44, 45, 46, 47, 48,  // 110 - 119
    49, 50, 51, np, np, np, np, np, np, np,  // 120 - 129
    np, np, np, np, np, np, np, np, np, np,  // 130 - 139
    np, np, np, np, np, np, np, np, np, np,  // 140 - 149
    np, np, np, np, np, np, np, np, np, np,  // 150 - 159
    np, np, np, np, np, np, np, np, np, np,  // 160 - 169
    np, np, np, np, np, np, np, np, np, np,  // 170 - 179
    np, np, np, np, np, np, np, np, np, np,  // 180 - 189
    np, np, np, np, np, np, np, np, np, np,  // 190 - 199
    np, np, np, np, np, np, np, np, np, np,  // 200 - 209
    np, np, np, np, np, np, np, np, np, np,  // 210 - 219
    np, np, np, np, np, np, np, np, np, np,  // 220 - 229
    np, np, np, np, np, np, np, np, np, np,  // 230 - 239
    np, np, np, np, np, np, np, np, np, np,  // 240 - 249
    np, np, np, np, np, np                   // 250 - 256
  };
  static const char cFillChar = '=';

  std::string::size_type nLength = sString.length();
  std::string            sResult;

  sResult.reserve(nLength);

  for(std::string::size_type nPos = 0; nPos < nLength; nPos++) {
    unsigned char c, c1;

    c = (char) DecodeTable[(unsigned char)sString[nPos]];
    nPos++;
    c1 = (char) DecodeTable[(unsigned char)sString[nPos]];
    c = (c << 2) | ((c1 >> 4) & 0x3);
    sResult.append(1, c);

    if(++nPos < nLength) {
      c = sString[nPos];
      if(cFillChar == c)
        break;

      c = (char) DecodeTable[(unsigned char)sString[nPos]];
      c1 = ((c1 << 4) & 0xf0) | ((c >> 2) & 0xf);
      sResult.append(1, c1);
    }

    if(++nPos < nLength) {
      c1 = sString[nPos];
      if(cFillChar == c1)
        break;

      c1 = (char) DecodeTable[(unsigned char)sString[nPos]];
      c = ((c << 6) & 0xc0) | c1;
      sResult.append(1, c);
    }
  }

  return sResult;
}

#endif // B64_BASE64_H 


When I try to compile, it gives me the errors:

`Base64' has not been declared
`decode' undeclared (first use this function)


I am using Dev-C++. Please help!
closed account (S6k9GNh0)
Deleted for good purposes.
Last edited on
You don't get it. I am MAKING a dll, and I want to EXPORT the base64_decode function, but it gives me errors.
You are defining the functions encode() and decode() as if they were class members. You cannot do that with namespaces. You have to define them within the Base64 namespace.

That is:

1
2
3
4
5
6
7
inline std::string Base64::encode(const std::string &sString) {
    ...
}

inline std::string Base64::decode(const std::string &sString) {
    ...
}

won't work. You need to do this:

1
2
3
4
5
6
7
8
9
namespace Base64 {
    inline std::string encode(const std::string &sString) {
        ...
    }

    inline std::string decode(const std::string &sString) {
        ...
    }
}


Lastly, you don't have a decode() function that returns a char*, and a std::string cannot be coerced into a char*.

HTH
I've never done it -- DLLs were not designed to work with namespaces and classes and the like.

The following links might be a good read:
http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/84a3c86285d8053b

Remember, namespaces and classes are C++ language constructs. DLLs only import/export global symbols (in other words, they don't handle namespaces and the like).

Of course, you can name the import/export symbols just about anything you want (I think... I can't check it for sure at the moment), and use that information with GetProcAddress() when you LoadLibrary().

Hope this helps.
Duoas:

we can export classes from the dll's. this is possible.


PickleMan:


your dll is correct.. i dont know how you are calling your dll function.
1. your dll must be creating a .lib file also. put the name of the lib in linker settings. and that path should be present in other library path settings. whenever you export anything from dll a lib file is created automatically which has declarations of the exported symbols.

2. second way what Duoas told you.
Correction -- you can export/import functions from a DLL -- including class functions. See the links I gave.

The class itself cannot be exported, because that is a C++ language construct.
If you sort out the cast of std::string to char* in base64_decode, the code compiles as is in Visual Studio.

In Windows, functions, data and entire classes may be exported/imported. Namespaces aren't entities in themselves, so can't be exported as such, but a namespace can span several DLLs.
Never mind, I solved it. I don't know how, but i fixed it.
Duoas:

I agree. :)
Topic archived. No new replies allowed.