If the exception you set in the DLL (a) will not leave the "black box of the process where it is running", then you don’t have to worry about serialization. If you have a DLL (b) or EXE (c) that reference the DLL (a), and their code catch to Exception, you are still in the same process box, and the exception is just one more object in memory, which is shared by all components (exe and dll) of the process. This is the case for most applications.
If your exception can escape the process - for example, you have a service with an external method that can throw the exception, then serialization needs to be implemented, so that it is sent to the client via "network" (it can be the real network, a named pipe between processes, or any other way where the object has to be transformed into a stream bytes). Other examples are whether you want to persist with the exception information on the disk, or for any reason perform the "in-hand" serialization of the exception (or an object containing it).
Note that even in situations where you want to transmit an error to a client (for example, in a web service), you rarely want to transmit the object of the exception directly, as it contains much more information that the client needs (for example, stack trace). In this case it is common to create Dtos (data transfer Objects) to contain only relevant information.